CCBill API Payment Widget integration guide

TypeScript/Node.js

The code example is written in TypeScript. It describes the steps required to perform authentication with the CCBill API and the payment token obtained using the CCBill API Payment Widget to perform the charge by payment token action (non-3DSecure and 3DSecure versions). This script covers the backend portion of the integration with the CCBill's RESTful Transaction API.

1. Install Dependencies

The backend code uses the Axios dependency to make HTTP requests. Install it with:

NPM:

npm install axios

Yarn:

yarn add axios

Begin by importing the axios library.

2. Define Endpoints

The endpoints section defines the API endpoints you will use throughout the process.

The example uses three endpoints to demonstrate the charge flow:

1. tokenEndpoint allows requesting the CCBill Auth (Bearer) token required for authentication in subsequent operations.

2. nonThreedsTransactionEndpoint allows performing a non-3DSecured charge transaction using the payment token.

3. threedsTransactionEndpoint allows performing a 3DSecured charge transaction using the payment token and previously obtained SCA parameters.

3. Provide Client Credentials

Set your Merchant Application ID as the value of clientId, and the Merchant Secret as the value of clientSecret.

The example code will set the accessToken value when the script executes.

4. Add Data

Provide the appropriate data for the request. To create a charge, the following parameters are obtained using the payment widget:

1. The paymentToken previously obtained using the widget.

Ensure the client's IP address is added as a payload ipAddress or header X-Origin-IP) parameter.

2. TransactionData, including the client account number, subaccount, the initial price, and period.

3. If using 3DS, provide the ThreedsParameters previously obtained using the payment widget.

5. Generate Token

Create a function to fetch the OAuth token (getOAuthToken). The function requires the client ID, client secret, and token endpoint to request the token.

The token helps authenticate the payment requests.

6. Charge Transaction and Handle Response

ThechargeTransactionfunction performs the charge based on the provided endpoint, data, payment token, and generated access token.

If calling the function throws no errors, the response is passed to the handleResponse function.

In this case, it only logs the response data. In a realistic scenario, it would allow you to continue processing the transaction and return the response to your client.

7. Test Transaction

The code fetches the OAuth token based on the previously provided data.

If the access token is generated successfully, the code performs a non-3DS transaction and then a 3DSecure transaction, using the previously obtained SCA and other transaction data.

		
import axios from 'axios';
interface TransactionData { clientAccnum: number; clientSubacc: number; initialPrice: number; initialPeriod: number; }
interface ThreedsParameters { threedsEci: string; threedsError: string; threedsStatus: string; threedsClientTransactionId: string; threedsAcsTransId: string; threedsDsTransId: string; threedsCurrency: string; threedsAmount: string; threedsCardToken: string; threedsVersion: string; threedsCavv: string; threedsXid: string; threedsSuccess: string; threedsAuthenticationType: string; threedsAuthenticationValue: string; } interface TransactionResponse { declineCode: number | undefined; declineText: string | undefined; denialId: number | undefined; approved: boolean; paymentUniqueId: string | undefined; sessionId: number | undefined; subscriptionId: number | undefined; newPaymentTokenId: number | undefined; } interface ApiResponse { status: number; data: TransactionResponse; } type ThreedsTransactionData = TransactionData & ThreedsParameters; // Endpoints const baseUrl = 'https://api.ccbill.com';
const tokenEndpoint = `${baseUrl}/ccbill-auth/oauth/token?grant_type=client_credentials`;
const nonThreedsTransactionEndpoint = `${baseUrl}/transactions/payment-tokens/`;
const threedsTransactionEndpoint = `${nonThreedsTransactionEndpoint}threeds/`;
// Client credentials
const clientId = 'YOUR-CLIENT-ID'; const clientSecret = 'YOUR-CLIENT-SECRET';
let accessToken: string | null = ''; // the access token will be obtained during script execution
// Requests data
const paymentToken = 'YOUR-PAYMENT-TOKEN';
const transactionData = { clientAccnum: 900684, clientSubacc: 0, initialPrice: 10, initialPeriod: 10, };
const threedsParameters = { threedsEci: '05', threedsError: '', threedsStatus: 'Y', threedsClientTransactionId: 'mcn-id-h76oy394utw', threedsAcsTransId: 'd6f15aae-2c9d-4333-a920-954be07c0c76', threedsDsTransId: 'd65e93c3-35ab-41ba-b307-767bfc19eae3', threedsCurrency: '978', threedsAmount: '10', threedsCardToken: '01ae5d142g7efb4b', threedsVersion: '2.2.0', threedsCavv: '', threedsXid: '', threedsSuccess: 'true', threedsAuthenticationType: '01', threedsAuthenticationValue: '5VdhGOTXBJw9+kEBOTtaJiLUAr8=', };
async function getOAuthToken(tokenEndpoint: string, clientId: string, clientSecret: string): Promise<string | null> { try { const response = await axios.post(tokenEndpoint, null, { auth: { username: clientId, password: clientSecret, }, }); if (response.status === 200) { return response.data.access_token; } else { console.log('Token request failed with status code:', response.status); console.log('Response content:', response.data); return null; } } catch (error) { console.error('Error while getting the OAuth token:', error); return null; } }
async function chargeTransaction(endpoint: string, accessToken: string, paymentToken: string, transactionData: TransactionData | ThreedsTransactionData): Promise<void> { const headers = { authorization: `Bearer ${accessToken}`, }; try { const response = await axios.post(`${endpoint}${paymentToken}`, transactionData, { headers, }); handleResponse(response); } catch (error) { console.error('Error while charging the transaction:', error); } }
function handleResponse(response: ApiResponse): void { if (response.status === 200) { console.log('Response:', response.data); } else { console.error('Error:', response.data); } }
(async () => { // Get access token accessToken = await getOAuthToken(tokenEndpoint, clientId, clientSecret);
if (accessToken) { // Charge regular transaction await chargeTransaction(nonThreedsTransactionEndpoint, accessToken, paymentToken, transactionData); // Charge threeds verified transaction await chargeTransaction(threedsTransactionEndpoint, accessToken, paymentToken, { ...transactionData, ...threedsParameters, }); } })();