Recurring payments
Perform merchant-initiated or card-on-file transactions.
Overview
Card components support two types of recurring payments:
- Merchant-initiated transactions (MITs): For subscription-based payments where the customer signs up and pays initially, and you then automatically charge them at a specified interval. This means there's no customer action needed for renewals.
- Card-on-file transactions with shopper consent: For storing payment methods with customer consent for future use. This allows you to provide a faster checkout experience for returning customers.
Merchant-initiated
Step 1: Set up the SDK config
To set up a recurring payment, you need to include the recurring
object in your transaction data of your sdkConfig
. You'll need to specify the frequency of this recurring payment (in days), but the expiration data is optional.
// Configure subscription transaction data
const transactionData = {
amount: 9.99,
currency: 'USD',
entryType: 'Ecom',
intent: 'Authorisation',
merchantTransactionId: 'sub-setup-123',
merchantTransactionDate: () => new Date().toISOString(),
shopper: {
email: '[email protected]',
firstName: 'John',
lastName: 'Doe'
},
recurring: {
frequencyInDays: 30,
frequencyExpiration: '2025-12-31'
}
};
// Create complete SDK configuration
const sdkConfig = {
transactionData, // ← This connects Step 1 to Step 2
apiKey: 'your-api-key',
environment: 'sandbox',
// ... other SDK settings
};
Step 2: Create your components
Next, you're going to use your sdkConfig
to create the relevant components. When the customer clicks submit, the recurring payments will start.
const cardNumberComponent = new CardNumberComponent(sdkConfig);
const cardExpiryComponent = new CardExpiryDateComponent(sdkConfig);
const cardCvcComponent = new CardCvcComponent(sdkConfig);
const cardSubmitComponent = new CardSubmitComponent(sdkConfig, {
cardNumberComponent,
cardExpiryDateComponent: cardExpiryComponent,
cardCvcComponent,
useCardOnFile: false,
submitText: 'Start subscription',
onPostAuthorisation: (result) => {
if (result.success) {
console.log('Subscription started!');
// The recurring data from step 1 was automatically used
}
}
});
// Mount components
cardNumberComponent.mount('card-number');
cardExpiryComponent.mount('card-expiry');
cardCvcComponent.mount('card-cvc');
cardSubmitComponent.mount('submit-button');
Card-on-file
Step 1: Set up the initial transaction
To save a card, you'll first need to ask for the customer's consent during the initial transaction. If the customer ticks the checkbox, their card details will be saved as a token for future reuse.
const transactionData = {
amount: 99.99,
currency: 'USD',
entryType: 'Ecom',
intent: 'Authorisation',
merchantTransactionId: 'order-12345',
merchantTransactionDate: () => new Date().toISOString(),
shopper: {
email: '[email protected]',
firstName: 'John',
lastName: 'Doe'
}
};
const sdkConfig = {
transactionData,
// ... other SDK configuration
};
// Create the card consent component
const cardConsentComponent = new CardConsentComponent(sdkConfig, {
label: 'Save this card for faster checkout in the future',
class: 'consent-checkbox'
});
// Create the card input components
const cardNumberComponent = new CardNumberComponent(sdkConfig);
const cardExpiryComponent = new CardExpiryDateComponent(sdkConfig);
const cardCvcComponent = new CardCvcComponent(sdkConfig);
// Create the card submit component
const cardSubmitComponent = new CardSubmitComponent(sdkConfig, {
cardNumberComponent,
cardExpiryDateComponent: cardExpiryComponent,
cardCvcComponent,
cardConsentComponent, // Include consent component
useCardOnFile: false, // Use a new card, not a saved card
submitText: 'Pay & save card',
onPostTokenisation: (tokenResult) => {
console.log('Card tokenised and saved:', tokenResult);
// Store the token reference in your system
},
onPostAuthorisation: (submitResult) => {
if (submitResult.success) {
console.log('Payment successful, card saved for future use');
}
}
});
// Mount components
cardNumberComponent.mount('card-number');
cardExpiryComponent.mount('card-expiry');
cardCvcComponent.mount('card-cvc');
cardConsentComponent.mount('card-consent');
cardSubmitComponent.mount('submit-button');
Step 2: Set up subsequent transactions
For subsequent transactions, you can use choose from:
- A traditional card selection: This is best for customers with multiple saved cards and provides full card management (edit, delete, update) but requires more interaction from the customer. It uses the card-on-file component.
- A streamlined click-once checkout: This is ideal for customers with one primary payment method and offers a faster checkout experience, but less flexibility. It uses the standalone click-once component.
- A hybrid approach: This combines the two components. It defaults to displaying a primary card, but allows customers to choose a different one if they want to.
const cardOnFileComponent = new CardOnFileComponent(sdkConfig, {
limitTokens: 10,
orderBy: {
lastUsageDate: { direction: 'desc', priority: 1 }
},
deleteCardButtonAriaLabel: 'Delete this card',
editCardInformationAriaLabel: 'Edit card details'
});
const clickOnceComponent = new ClickOnceStandaloneComponent(sdkConfig, {
limitTokens: 1,
isCvcRequired: false,
submitText: 'Complete purchase',
disableCardSelection: true
});
// Primary checkout with click-once
const quickCheckout = new ClickOnceStandaloneComponent(sdkConfig, {
limitTokens: 1,
submitText: 'Pay with Primary Card',
class: 'primary-checkout'
});
// Alternative with full card selection
const alternativeCheckout = new CardOnFileComponent(sdkConfig, {
limitTokens: 5,
class: 'alternative-checkout hidden' // Initially hidden
});
// Toggle between interfaces
const showAlternativeButton = document.createElement('button');
showAlternativeButton.textContent = 'Use different card';
showAlternativeButton.onclick = () => {
document.querySelector('.primary-checkout').classList.add('hidden');
document.querySelector('.alternative-checkout').classList.remove('hidden');
};
Updated 3 days ago