Installation
Integration
To integrate the Card Enrollment SDK into your web application, follow these steps:
1. Loading the JS file
Begin by loading the JavaScript file provided by us. You can find it at the following URL:
<script
type="text/javascript"
src="https://sdk.astrada.co/v1/cardEnrollmentSdk.js"
data-id="card-enrollment-sdk"
></script>2. Launching the SDK
Once you have added the script to your website, it will register a global variable named CardEnrollmentSdk. This variable provides the following methods:
CardEnrollmentSdk.openForm(config): launches the Card Enrollment SDK, used for enrolling cards, and initiates the verification process of the card.CardEnrollmentSdk.closeForm(): closes the Card Enrollment SDK.CardEnrollmentSdk.setStyle(style): applies your brand theme to the SDK (see Visual Customization).
See the next section to learn about the different configurations supported when calling the openForm method.
Configuration
In this section, you will learn how to configure the parameters when calling the CardEnrollmentSdk.openForm(config)method. The following config parameters are supported:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
companyName | string | Yes | The name of the company using card linking | "Your company name" |
subaccountId | string | Yes | A valid UUID of the Astrada subaccount where the card should be enrolled | "67bc3887-4e25-49cf-bea7-326d808acb5f" |
terms.text | string | No | Markdown text for a customizable consent message | By checking this box, you are indicating that you agree to the terms and policy. |
terms.privacyUrl | string | No | URL to privacy documentation | https://yourcompany.com/privacy |
terms.termsUrl | string | No | URL to terms and conditions documentation | https://yourcompany.com/terms |
statusLabels.creatingSubscription | string | No | Overrides the progress message shown while the card subscription is created | Securely connecting your card |
statusLabels.startingVerification | string | No | Overrides the progress message shown while card verification starts | Contacting your bank |
statusLabels.verifying | string | No | Overrides the progress message shown while the card is verified | Verifying with your bank |
statusLabels.finishing | string | No | Overrides the progress message shown while enrollment is finalized | Finalizing your enrollment |
customerReferenceId | string | No | A valid UUID used to correlate the card enrolment | "67bc3887-4e25-49cf-bea7-326d808acb5f" |
getAccessToken | function | Yes | An asynchronous function that returns a valid Access Token to request Astrada's API | |
getAccessTokenTimeoutMs | number | No | Milliseconds to wait for getAccessToken to resolve before the token fetch times out. Defaults to 5000. | 5000 |
onConnect | function | No | Function to be triggered when the SDK connects to your page, before the enrollment form renders | |
onSuccess | function | No | Function to be triggered when the cardholder successfully enrolls a card | |
onError | function | No | Function to be triggered when an error occurs during the card enrollment (e.g. failure to create a card subscription, verify the card, etc) | |
onCancel | function | No | Function to be triggered when the cardholder abandons/cancels the enrollment flow | |
container | HTMLElement | No | The HTML element in which the SDK should be rendered. | document.querySelector(“#container-div”) |
metadata | object | No | Reserved. Accepted and validated, but not currently forwarded to the enrollment API, so it has no runtime effect yet. | {"orderId": "1234"} |
CardEnrollmentSdk.openForm({
companyName: "Your company name",
subaccountId: "67bc3887-4e25-49cf-bea7-326d808acb5f",
getAccessToken: async () => 'valid-json-web-token',
getAccessTokenTimeoutMs: 5000, // optional, raise if your token exchange is slow (default 5000)
onConnect: () => console.log("The SDK connected to the page."),
onSuccess: (data) => console.log(data),
onError: (data) => console.log(data),
onCancel: () => console.log("The user abandoned the enrollment flow."),
terms: {
text: "By checking this box, you are indicating that you agree to the [terms](https://yourcompany.com/terms) and [policy](https://yourcompany.com/policy)."
}
// Add more configuration parameters here if needed
...
});TypeScript types
Astrada publishes official TypeScript types for the SDK, @astrada.co/card-enrollment-sdk. The package contains type declarations only, with no runtime code, so install it as a dev dependency; it adds nothing to your bundle, and the SDK still loads from the hosted script above. Importing it also declares the CardEnrollmentSdk global, so you don't hand-write a .d.ts:
npm install --save-dev @astrada.co/card-enrollment-sdkimport type {
CardEnrollmentSdkConfig,
EnrollmentSuccess, // the onSuccess payload
OnErrorPayload, // the onError payload
SdkStyle, // the setStyle argument
} from "@astrada.co/card-enrollment-sdk";The types are generated from the SDK source and checked against it in CI, so they match what the runtime sends.
Authentication
The Card Enrollment SDK uses a separate set of credentials from the main API. During onboarding, you'll receive dedicated SDK credentials (client_id + client_secret) scoped specifically for card enrollment operations.
The getAccessToken passed to the openForm must be an asynchronous function responsible for returning an Access Token (JWT). Your backend should use the SDK credentials to obtain this token from Astrada's OAuth endpoint, then return it to the frontend. This function must resolve within the configured timeout, 5 seconds by default. If your token exchange is slower, raise the limit with the getAccessTokenTimeoutMs option (in milliseconds). Otherwise, it will timeout and return an error, resulting in a failed enrollment.
The Access Token is fetched at two different points in time:
- When the SDK is launched.
- When the Access Token being used expires.
See the Authentication Guide for full details on credential types, the token exchange flow, and security best practices.
Never use anyclient_idorclient_secretdirectly in browser code. Your backend must exchange the SDK credentials for a token and pass only the resulting JWT to the frontend viagetAccessToken.
Callbacks

Callbacks provide information about events that occur during the card enrollment process.
| Event | Description |
|---|---|
onConnect | Triggered when the SDK connects to your page, before the enrollment form renders. |
No payload.
| Event | Description |
|---|---|
onSuccess | Triggered when the customer successfully enrolls a card and activates a card subscription. |
Example Payload:
{
"subscriptionId": "1c6db37a-333a-4379-8ac5-0f819f2c0bf7",
"cardId": "8309b5f8-d5d8-49bb-9001-38bf1bb0f1e4",
"enrollmentGuidance": {
"availableEnrollmentMethods": [
"cardholder-single"
]
},
"authenticationFlow": "frictionless"
}
onSuccessalso returns the enrolledcardIdand the 3DSauthenticationFlow(challenge,frictionless, ornull). To retrieve card details as well as the latest subscriptionstatus, you can use thesubscriptionIdto call the GET Card Subscription endpoint.
| Event | Description |
|---|---|
onError | Indicates an error during the card enrollment process, such as failure to create a card subscription or verify the card. |
Example Payload (Server Error):
{
"type": "server",
"error": {
"detail": "Card verification step with id=d397da41-95ac-4bb0-82da-cd78d10d06ff for card verification with id=ed146b4a-8e48-4c7f-b284-62eb64dca7bb can not be completed at this state",
"title": "Bad Request"
},
"verificationId": "ed146b4a-8e48-4c7f-b284-62eb64dca7bb",
"cardId": "8309b5f8-d5d8-49bb-9001-38bf1bb0f1e4",
"subscriptionId": "1c6db37a-333a-4379-8ac5-0f819f2c0bf7"
}Example Payload (Client Error):
{
"type": "client",
"error": {
"detail": "Card subscription data is undefined."
}
}When the failure happens after the card subscription and verification exist,
onErroralso includes the discreteverificationId,cardId, andsubscriptionIdfields (all optional, omitted for pre-create rejections such as an invalid CVC or an ineligible card). PassverificationIdto GET Card Verification to read the verification'sfailureReason.
| Event | Description |
|---|---|
onCancel | Indicates that the customer canceled the enrollment flow, typically by clicking on the exit button, outside the SDK's frame, or by pressing the ESC key on the keyboard. |
No payload.
Customization
Consent Message
Approved Consent Language:
It is mandatory to collect two separate consents: (1) Network Consent and; (2) Astrada & Customer Consent. The Network Consent language will always be shown and isn't customizable, whereas the Astrada & Customer Consent language is.
Network Consent: By submitting your card information and checking this box, you authorize your [Card Network] to access, monitor, and share transaction data (e.g., amount, time, date, and merchant name) with Astrada (our service provider) for the purposes of identifying relevant transactions and carrying out related spend management services. You also affirm that the card being monitored is used primarily for business purposes.
Astrada & Customer Consent: By submitting your card information and checking this box, you affirm your consent so that Astrada may process said data in accordance with [(Customer Name)’s Terms and Conditions], [(Customer Name)’s Privacy Policy], and Astrada’s Privacy Policy. You also acknowledge and agree that relevant transaction details may be shared with involved third parties to enable spend management processes, in accordance with Astrada's Privacy Policy. You may opt out of transaction monitoring on the payment card you entered at any time by going to your account settings.
Rely on the default consent language
If the terms object is not passed to the openForm, the default language will be shown, without customizable terms.

Customize links within the Customer default consent language
If you want to rely on both consent languages, network-specific and customer, you can proceed with the default consent message and insert your company's Privacy Policy and Terms & Conditions, follow the example below:
CardEnrollmentSdk.openForm({
companyName: "",
subaccountId: "",
getAccessToken: async () => "<access token>",
terms: {
privacyUrl: "YOUR_PRIVACY_URL_HERE",
termsUrl: "YOUR_TERMS_URL_HERE",
}
});
Customize customer consent language
To set up a fully customizable consent message, use the following code snippet::
CardEnrollmentSdk.openForm({
companyName: "",
subaccountId: "",
getAccessToken: async () => "<access token>",
terms: {
text: "By checking this box, you are indicating that you agree to the [terms](https://yourcompany.com/terms) and [policy](https://yourcompany.com/policy).",
}
});To proceed with the default consent message and insert your company's Privacy Policy and Terms & Conditions, follow the example below:


Customize where the SDK should be rendered
To customize where the SDK is rendered on your page, follow the example below:
CardEnrollmentSdk.openForm({
companyName: "",
subaccountId: "",
getAccessToken: async () => "<access token>",
container: document.querySelector("#container-div")
});The SDK will render at full-page scale if the HTML element is absent.
Handling specific errors and closing the SDK
In some scenarios, it may be necessary to close the SDK when a specific error occurs to allow the client to proceed with an alternative flow. For example, if a cardholder attempts to enroll a network-bulk eligible card, the operation will fail with this error.
In such cases, the client can intercept the onError callback, close the SDK, and allow you to proceed with your own custom logic.
The following example demonstrates how to handle this use case:
CardEnrollmentSdk.openForm({
...
onSuccess: (data) => console.log(data),
onError: (data) => {
const networkBulkError = "card_subscription.card_must_be_network_bulk_enrolled";
const { errorCode } = data.error;
if (errorCode == networkBulkError) {
CardEnrollmentSdk.closeForm();
}
},
onCancel: onCancel,
...
});Progress Messages
Creating the card subscription and verifying the card can take some time. To make the wait easier to follow, the SDK shows a short progress checklist that advances through the enrollment: Securely connecting your card → Contacting your bank → Verifying with your bank → Finalizing your enrollment.
Rely on the default progress messages
If statusLabels is not passed to openForm, the built-in messages above are shown.
Customize the progress messages
Pass statusLabels to override any subset of the stage messages; omitted stages keep the built-in copy. Each key maps to a stage of the enrollment:
CardEnrollmentSdk.openForm({
companyName: "",
subaccountId: "",
getAccessToken: async () => "<access token>",
statusLabels: {
creatingSubscription: "Securely connecting your card",
startingVerification: "Contacting your bank",
verifying: "Talking to your card issuer",
finishing: "Finalizing your enrollment",
},
});Troubleshooting
Having issues integrating with the SDK? See our Troubleshooting Guide.
Updated 6 days ago