Interswitch card payments
18 AI agent skills for Interswitch API integration — automate payment workflows with TypeScript, Node.js, and Next.js
npx -y skills add rexedge/interswitch --skill interswitch-card-paymentsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Interswitch Card Payments API — process card transactions directly via API, handle 3D Secure (Visa/Mastercard), Hosted Fields for PCI compliance, and Google Pay. Use this skill whenever building a custom card payment flow, implementing 3D Secure authentication, using Hosted Fields for PCI-compliant card collection, integrating Google Pay, or processing direct card charges. Also use when you see references to authData, 3DSecure, OTP validation, Hosted Fields, payment-api endpoint, or card PIN/OTP submission.
SKILL.md
7.1 KB, ~1.7k tokens by cl100k_base, as published. Nobody here has run it
Interswitch Card Payments API
Process card payments directly via the Interswitch API with 3D Secure support, Hosted Fields, and Google Pay integration.
Card Payment Flow
- Collect card details (PAN, expiry, CVV, PIN)
- Encrypt card data into
authData - Send payment request with encrypted authData
- Handle OTP/3D Secure if required
- Verify transaction server-side
Test Credentials (Card Payment API)
| Parameter | Value |
|---|---|
| Client ID | IKIA3B827951EA3EC2E193C51DA1D22988F055FD27DE |
| Secret Key | ajkdpGiF6PHVrwK |
| Merchant Code | MX21696 |
| Pay Item ID | 4177785 |
Card Data Encryption (authData)
Card details must be encrypted before transmission. The authData is a concatenation of card PAN, PIN, expiry, and CVV encrypted with the Interswitch modulus/exponent:
import crypto from 'crypto';
interface CardDetails {
pan: string; // Card number (no spaces)
pin: string; // 4-digit PIN
expiryDate: string; // YYMM format
cvv: string; // CVV/CVC
}
function generateAuthData(card: CardDetails): string {
// Concatenate: 1PAN + 0PIN + EXPIRY + CVV (with length-prefixed fields)
const cardData = `1${card.pan}0${card.pin}${card.expiryDate}${card.cvv}`;
// Use Interswitch's public key for encryption
// Get the actual modulus and exponent from Interswitch documentation
const publicKey = crypto.createPublicKey({
key: {
kty: 'RSA',
n: '<INTERSWITCH_MODULUS_BASE64URL>',
e: 'AQAB', // 65537
},
format: 'jwk',
});
const encrypted = crypto.publicEncrypt(
{ key: publicKey, padding: crypto.constants.RSA_PKCS1_PADDING },
Buffer.from(cardData)
);
return encrypted.toString('base64');
}
Direct Card Payment
interface CardPaymentRequest {
customerId: string;
amount: string; // In minor currency (kobo)
currency: string; // '566' for NGN
transactionRef: string;
authData: string; // Encrypted card data
}
interface CardPaymentResponse {
amount: string;
responseCode: string;
responseDescription: string;
paymentId: string;
transactionRef: string;
remittanceAmount: string;
eciFlag?: string;
message?: string;
}
async function initiateCardPayment(
payment: CardPaymentRequest
): Promise<CardPaymentResponse> {
const headers = await getAuthHeaders();
const response = await fetch(
`${getConfig().collectionsBaseUrl}/collections/api/v1/pay`,
{
method: 'POST',
headers,
body: JSON.stringify(payment),
}
);
return response.json();
}
Handle OTP Validation
If responseCode is T0 (OTP required):
interface OTPValidationRequest {
paymentId: string;
transactionRef: string;
otp: string;
}
async function validateOTP(
request: OTPValidationRequest
): Promise<CardPaymentResponse> {
const headers = await getAuthHeaders();
const response = await fetch(
`${getConfig().collectionsBaseUrl}/collections/api/v1/pay/validate`,
{
method: 'POST',
headers,
body: JSON.stringify(request),
}
);
return response.json();
}
3D Secure Transactions
For Visa/Mastercard 3D Secure:
// Step 1: Initiate payment — if 3DS required, response includes:
// - responseCode: 'Z9' or 'S0'
// - eciFlag with redirect info
interface ThreeDSecureResponse {
responseCode: string;
redirectUrl: string; // Redirect customer to this URL
transactionId: string;
md: string; // Merchant Data for callback
}
// Step 2: Customer completes 3DS on bank's page
// Step 3: Bank redirects back to your callback URL
// Step 4: Complete the transaction
async function complete3DSTransaction(
paymentId: string,
transactionRef: string,
eciFlag: string
): Promise<CardPaymentResponse> {
const headers = await getAuthHeaders();
const response = await fetch(
`${getConfig().collectionsBaseUrl}/collections/api/v1/pay/validate`,
{
method: 'POST',
headers,
body: JSON.stringify({ paymentId, transactionRef, eciFlag }),
}
);
return response.json();
}
Hosted Fields (PCI Compliant)
Hosted Fields let you collect card data securely without handling raw card numbers. Interswitch hosts the input fields in iframes:
<!-- Include Hosted Fields SDK -->
<script src="https://newwebpay.qa.interswitchng.com/hosted-fields.js"></script>
<div id="card-number"></div>
<div id="card-expiry"></div>
<div id="card-cvv"></div>
<div id="card-pin"></div>
<button id="submit-payment">Pay</button>
<script>
const hostedFields = window.interswitchHostedFields({
merchantCode: 'MX6072',
payItemId: '9405967',
transactionRef: 'TXN_' + Date.now(),
amount: 10000,
currency: 566,
mode: 'TEST',
fields: {
cardNumber: { selector: '#card-number', placeholder: 'Card Number' },
expirationDate: { selector: '#card-expiry', placeholder: 'MM/YY' },
cvv: { selector: '#card-cvv', placeholder: 'CVV' },
pin: { selector: '#card-pin', placeholder: 'PIN' },
},
onComplete: function (response) {
console.log(response);
},
});
document.getElementById('submit-payment').addEventListener('click', () => {
hostedFields.submit();
});
</script>
Google Pay Integration
// Step 1: Check Google Pay availability
const paymentsClient = new google.payments.api.PaymentsClient({
environment: 'TEST', // or 'PRODUCTION'
});
const isReadyToPayRequest = {
apiVersion: 2,
apiVersionMinor: 0,
allowedPaymentMethods: [{
type: 'CARD',
parameters: {
allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
allowedCardNetworks: ['VISA', 'MASTERCARD'],
},
tokenizationSpecification: {
type: 'PAYMENT_GATEWAY',
parameters: {
gateway: 'interswitch',
gatewayMerchantId: 'MX6072',
},
},
}],
};
// Step 2: Request payment
const paymentDataRequest = {
...isReadyToPayRequest,
transactionInfo: {
totalPriceStatus: 'FINAL',
totalPrice: '100.00',
currencyCode: 'NGN',
},
merchantInfo: { merchantName: 'Your Store' },
};
const paymentData = await paymentsClient.loadPaymentData(paymentDataRequest);
// Step 3: Send paymentData.paymentMethodData.tokenizationData.token to your server
// Step 4: Process token via Interswitch API
Security Best Practices
- Never log raw card data — Only handle encrypted authData
- Use Hosted Fields when possible for PCI compliance
- Always verify server-side — Requery every transaction
- Handle all response codes — Implement proper error flows for OTP, 3DS
- Use unique transaction references — Prevent duplicate charges