implementation-guide
Implementation Guide
This guide walks through some steps to create a Network Token and process it with Reactors while keeping you in PCI compliance.
Install the SDK
This example demonstrates how to implement a Network Token workflow using BasisTheory Node SDK. You can also use our SDKs for other languages or call our REST APIs directly.
Initialize the Client
import { BasisTheoryClient } from "@basis-theory/node-sdk";
const client = new BasisTheoryClient({
apiKey: "YOUR_PRIVATE_API_KEY"
});
Create a Network Token
Create a Network Token using your Private Application. You can create tokens from existing card Tokens, Token Intents, or raw card data:
import { BasisTheoryClient } from "@basis-theory/node-sdk";
const client = new BasisTheoryClient({
apiKey: "YOUR_PRIVATE_API_KEY"
});
async function createNetworkToken() {
try {
// Using an existing Token ID
const networkToken = await client.networkTokens.create({
tokenId: "c06d0789-0a38-40be-b7cc-c28a718f76f1",
cardholderInfo: {
name: "John Doe",
address: {
line1: "123 Main Street",
line2: "Apt 4B",
line3: "Building 7",
city: "Beverly Hills",
postalCode: "90210",
stateCode: "CA",
countryCode: "USA"
}
}
});
console.log('Network Token created:', networkToken.id);
console.log('Status:', networkToken.status);
return networkToken;
} catch (error) {
console.error('Error creating Network Token:', error);
throw error;
}
}
Generate Cryptogram
A cryptogram is a transaction-specific security code generated by the issuer for a Network Token. You might need to generate this cryptographic proof before processing any payment to provide enhanced validation for each transaction request.
This is usually only required for a one time transaction or when setting up the initial recurring transaction, however this might need to be validated with your payment provider.
async function generateCryptogram(networkTokenId) {
try {
const cryptogram = await client.networkTokens.cryptogram(networkTokenId);
console.log('Cryptogram generated:', cryptogram.cryptogram);
console.log('ECI:', cryptogram.eci);
return cryptogram;
// Response example: { cryptogram: "2z8pd6WGPUi/BBesvjJcyw==", eci: "07" }
} catch (error) {
console.error('Error generating cryptogram:', error);
throw error;
}
}
Process payment using your payment provider API using a Pre-Configured Proxy
This approach keeps all sensitive data processing within Basis Theory's secure environment while allowing you to integrate with any payment provider that accepts external generated network tokens.
For more information of how to setup a proxies follow this page
Adapt the payload structure in the proxy code to match your specific payment provider's API requirements.
- Adyen
const { BasisTheoryClient } = require('@basis-theory/node-sdk-2');
const {Client, Config, CheckoutAPI} = require('@adyen/api-library');
module.exports = async function (req) {
const {applicationOptions: {apiKey}, args, configuration} = req;
const {ADYEN_API_KEY, ADYEN_MERCHANT_ACCOUNT} = configuration;
const bt = new BasisTheoryClient({apiKey});
const {networkToken} = args.body;
const cryptogramData = await bt.networkTokens.cryptogram(networkToken.id);
const requestData = {
amount: {currency: 'USD', value: 100},
reference: 'ORDER-12345',
merchantAccount: ADYEN_MERCHANT_ACCOUNT,
paymentMethod: {
type: 'networkToken',
number: networkToken.number,
expiryMonth: networkToken.expiryMonth,
expiryYear: networkToken.expiryYear,
brand: 'visa',
holderName: 'John Doe',
},
mpiData: {
directoryResponse: 'Y',
authenticationResponse: 'Y',
tokenAuthenticationVerificationValue: cryptogramData.cryptogram,
eci: cryptogramData.eci
},
shopperInteraction: 'Ecommerce',
recurringProcessingModel: 'Subscription',
shopperReference: 'CUSTOMER_ID_123'
};
const config = new Config({
apiKey: ADYEN_API_KEY,
merchantAccount: ADYEN_MERCHANT_ACCOUNT,
environment: "TEST"
});
const client = new Client({config});
const checkoutClient = new CheckoutAPI(client);
const result = await checkoutClient.payments(requestData);
return {
body: result
};
};
curl -L -X POST 'https://api.basistheory.com/proxies/YOUR_PROXY_ID' \
-H 'BT-API-KEY: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data-raw '{
"name": "Adyen Call with NT proxy",
"destination_url": "https://echo.basistheory.com/anything",
"require_auth": false,
"request_transform": {
"type": "code",
"code": "YOUR_PRE_REQUEST_CODE_HERE"
},
"application": {
"id": "APPLICATION_ID_HERE"
},
"configuration": {
"ADYEN_API_KEY": "YOUR_ADYEN_API_KEY",
"ADYEN_MERCHANT_ACCOUNT": "YOUR_ADYEN_MERCHANT_ACCOUNT"
}
}'
curl -L 'https://api.basistheory.com/proxy' \
-H 'BT-API-KEY: YOUR_API_KEY' \
-H 'BT-PROXY-KEY: YOUR_PROXY_KEY' \
-H 'Content-Type: application/json' \
-d '{
"networkToken":{
"id": "{{ network_token: YOUR_NETWORK_TOKEN_ID | json: \"$.id\" }}",
"number": "{{ network_token: YOUR_NETWORK_TOKEN_ID | json: \"$.data.number\" }}",
"expiryMonth": "{{ network_token: YOUR_NETWORK_TOKEN_ID | json: \"$.data.expiration_month\" }}",
"expiryYear": "{{ network_token: YOUR_NETWORK_TOKEN_ID | json: \"$.data.expiration_year\" }}"
}
}'
async function completePaymentFlow() {
try {
// Step 1: Create Network Token (assuming you have this function)
const networkToken = await createNetworkToken();
// Step 2: Process payment using the proxy
const response = await fetch('https://api.basistheory.com/proxy', {
method: 'POST',
headers: {
'BT-API-KEY': 'YOUR_API_KEY',
'BT-PROXY-KEY': 'YOUR_PROXY_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
networkToken: {
id: `{{ network_token: ${networkToken.id} | json: "$.id" }}`,
number: `{{ network_token: ${networkToken.id} | json: "$.data.number" }}`,
expiryMonth: `{{ network_token: ${networkToken.id} | json: "$.data.expiration_month" }}`,
expiryYear: `{{ network_token: ${networkToken.id} | json: "$.data.expiration_year" }}`
}
})
});
const result = await response.json();
if (response.ok) {
console.log('Payment completed successfully!', result);
return result;
} else {
console.log('Payment failed:', result);
throw new Error(result.error || 'Payment failed');
}
} catch (error) {
console.error('Payment flow error:', error);
throw error;
}
}