@mygigsters/card-sdk
v1.0.3
Published
MyGigsters Card SDK - Embed a secure single-step card saving payment form into any website.
Maintainers
Readme
@mygigsters/card-sdk
Embed a secure, single-step card saving form into any web application — powered by Airwallex Payment Elements.
Table of Contents
- Overview
- Features
- Requirements
- Installation
- Get Client Info (API)
- Quick Start
- Module Formats
- Usage Examples
- Configuration Reference
- API Reference
- Success Response
- Callback Reference
- Environments
- Theming
- Error Handling
- Security
- TypeScript
- Troubleshooting
- Changelog
Overview
The MyGigsters Card SDK renders a secure, self-contained modal that lets your customers save their payment card in a single step. The SDK:
- Uses a pre-fetched Bearer token retrieved from
GET /api/v1/client/me— no API keys or secrets are ever shared with or stored inside the SDK. - Embeds an Airwallex Payment Element inside a closed Shadow DOM — your host page styles never leak in and vice versa.
- Returns a
paymentConsentIdon success — no raw card data ever touches your server.
Features
- Pre-fetched Token Auth — Client pre-fetches a JWT token via
/client/mebefore passing it to the SDK. - Airwallex-powered card tokenization — PCI-compliant card element embedded in an isolated iframe.
- Shadow DOM isolation — No CSS conflicts with your app.
- Light & Dark themes — Toggle at init time or at runtime.
- Zero React dependency — Works in any JavaScript app (React, Vue, Angular, plain HTML).
- Multiple module formats — ESM, CJS, CDN (UMD).
- TypeScript — Full type definitions included (
dist/index.d.ts). - Webhook support — Optionally POST the success payload to your own endpoint.
Requirements
| Requirement | Version | |-------------|---------| | Browser | Chrome 80+, Firefox 78+, Safari 14+, Edge 80+ | | Node.js (build/dev only) | ≥ 14.0.0 | | React (optional) | ≥ 18.0.0 |
Note: The SDK must be served over HTTPS (or
localhostfor development). Airwallex payment elements require a secure context.
Installation
# npm
npm install @mygigsters/card-sdk
# yarn
yarn add @mygigsters/card-sdk
# pnpm
pnpm add @mygigsters/card-sdkGet Client Info (API)
Before initializing the Card SDK, you need your Bearer token, myGigsterId, and the customer's customerId. Call GET /api/v1/client/me using HTTP Basic Auth (uuid:randomPasswordShowOnce) to retrieve your token and myGigsterId. Obtain customerId by creating a customer via POST /api/v1/customer.
Endpoint
GET /api/v1/client/me| Environment | URL |
|-------------|-----|
| Demo / QA | https://qa-payments.mygigsters.com.au/api/v1/client/me |
| Production | https://prod-payments.mygigsters.com.au/api/v1/client/me |
Headers
Content-Type: application/json
x-api-version: 1.1
Authorization: Basic {base64_encoded_combination of uuid:randomPasswordShowOnce}Example Request
curl --location 'https://qa-payments.mygigsters.com.au/api/v1/client/me' \
--header 'Content-Type: application/json' \
--header 'x-api-version: 1.1' \
--header 'Authorization: Basic MGI3YjFiMTctOTJhZC00Yjc4LWFhN2ItNjI2ODBhOWUzOGExOkt1aFNEa3NCVmFXQFNPQyhZQCFh'Example Response (200 OK)
{
"success": true,
"status": 200,
"data": {
"id": 1,
"myGigsterId": "4407c3ba-10c9-4822-9f51-c2c96692f8d7",
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"fullName": "Nitesh ",
"email": "[email protected]",
"businessName": "MG Nitesh Agrwal Deswal",
"address": null,
"acn": "123456789",
"phone": "9876543210"
}
}Response Fields for Card SDK
| Field | Type | Description |
|-------|------|-------------|
| data.token | string | Required by SDK: Bearer JWT token required to authenticate SDK requests. Pass as token in init(). |
| data.myGigsterId | string | Required by SDK: Your unique MyGigsters client account identifier. Pass as myGigsterId in init(). |
| data.fullName | string | Registered full name of the client. |
| data.email | string | Registered contact email address. |
| data.businessName | string | Registered business or entity name. |
Quick Start
1. Add a container element in your HTML:
<div id="mygigsters-card"></div>2. Initialize the SDK:
import { MygigstersCardSDK } from '@mygigsters/card-sdk';
const sdk = new MygigstersCardSDK();
await sdk.init({
token: 'your_jwt_token', // from GET /api/v1/client/me
customerId: 'cus_hkdmcdjshhknkk4lc2t',
myGigsterId: '4407c3ba-10c9-4822-9f51-c2c96692f8d7',
containerId: 'mygigsters-card',
env: 'demo',
onSuccess: (res) => console.log('Card saved! Consent ID:', res.paymentConsentId),
onError: (err) => console.error('Error:', err.message),
onClose: () => console.log('Modal closed'),
});The card modal opens automatically after init() resolves.
Module Formats
| Format | Path | Use Case |
|--------|------|----------|
| ESM | dist/index.esm.js | Modern bundlers (Vite, Webpack 5, Rollup) |
| CommonJS | dist/index.cjs.js | Node.js / require() environments |
| CDN (UMD) | cdn/card-sdk-entry.js | Browser <script> tag / self-hosted CDN |
| TypeScript | dist/index.d.ts | Type definitions |
Usage Examples
ES Modules (Recommended)
import { MygigstersCardSDK } from '@mygigsters/card-sdk';
const sdk = new MygigstersCardSDK();
await sdk.init({
token: 'your_jwt_token', // from GET /api/v1/client/me
customerId: 'cus_hkdmcdjshhknkk4lc2t',
myGigsterId: '4407c3ba-10c9-4822-9f51-c2c96692f8d7',
containerId: 'mygigsters-card',
env: 'demo', // 'demo' | 'prod'
mode: 'dark', // optional: 'dark' (default) | 'light'
onSuccess: (res) => {
console.log('✅ Card saved:', res.paymentConsentId);
// Pass res.paymentConsentId to the MyGigsters API to charge the customer
},
onError: (err) => {
console.error('❌ Error:', err.message);
},
onClose: () => {
console.log('Modal closed by user');
},
});CommonJS
const { MygigstersCardSDK } = require('@mygigsters/card-sdk');
const sdk = new MygigstersCardSDK();
sdk.init({
token: 'your_jwt_token', // from GET /api/v1/client/me
customerId: 'cus_hkdmcdjshhknkk4lc2t',
myGigsterId: '4407c3ba-10c9-4822-9f51-c2c96692f8d7',
containerId: 'mygigsters-card',
onSuccess: (res) => console.log('Card saved:', res.paymentConsentId),
onError: (err) => console.error('Error:', err.message),
onClose: () => console.log('Closed'),
});CDN / Browser Script Tag
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>My App</title>
</head>
<body>
<!-- 1. Mount target -->
<div id="mygigsters-card"></div>
<!-- 2. Load the SDK -->
<script src="https://qa-payments.mygigsters.com.au/card-sdk-entry.js"></script>
<script>
async function openCardForm(token) {
await MygigstersCard.init({
token: token, // from GET /api/v1/client/me
customerId: 'cus_hkdmcdjshhknkk4lc2t',
myGigsterId: '4407c3ba-10c9-4822-9f51-c2c96692f8d7',
containerId: 'mygigsters-card',
env: 'demo',
mode: 'dark',
onSuccess: (res) => console.log('✅ Card saved:', res.paymentConsentId),
onError: (err) => console.error('❌ Error:', err.message),
onClose: () => console.log('Closed'),
});
}
</script>
</body>
</html>CDN global: The CDN build exposes
window.MygigstersCard(notMygigstersCardSDK).
React (useEffect)
import { useEffect } from 'react';
import { MygigstersCardSDK } from '@mygigsters/card-sdk';
function SaveCardForm({ token, customerId, myGigsterId }) {
useEffect(() => {
if (!token) return;
const sdk = new MygigstersCardSDK();
sdk.init({
token,
customerId,
myGigsterId,
containerId: 'mygigsters-card',
env: 'demo',
mode: 'dark',
onSuccess: (res) => console.log('Card saved!', res.paymentConsentId),
onError: (err) => console.error(err),
onClose: () => console.log('Closed'),
});
// Cleanup on unmount
return () => sdk.destroy();
}, [token, customerId, myGigsterId]);
return <div id="mygigsters-card" />;
}Configuration Reference
Pass these options to init():
| Parameter | Type | Required | Default | Description |
|-----------|------|:--------:|---------|-------------|
| token | string | ✅ | — | Bearer JWT token obtained from GET /api/v1/client/me |
| customerId | string | ✅ | — | MyGigsters customer ID for whom the card is saved (from POST /api/v1/customer) |
| myGigsterId | string | ✅ | — | Unique client account identifier (from GET /api/v1/client/me) |
| containerId | string | ✅ | — | id of the DOM element to mount the SDK into |
| env | 'dev' \| 'demo' \| 'prod' | ❌ | 'demo' | Target environment |
| baseUrl | string | ❌ | — | Custom base URL override (for self-hosted deployments) |
| mode | 'light' \| 'dark' | ❌ | 'dark' | UI color theme |
| onSuccess | (res) => void | ❌ | no-op | Fired after the card is saved successfully |
| onError | (error) => void | ❌ | console.error | Fired on any SDK or network error |
| onClose | () => void | ❌ | no-op | Fired when the user closes the modal |
| webhookUrl | string | ❌ | — | URL to POST the success payload to automatically |
| onWebhook | (payload) => void | ❌ | no-op | JS callback for receiving the webhook payload in real-time |
API Reference
init(config)
Validates configuration, builds the Shadow DOM modal, initializes the Airwallex card element, and automatically calls show().
import { MygigstersCardSDK } from '@mygigsters/card-sdk';
const sdk = new MygigstersCardSDK();
await sdk.init(config);
// or, via CDN:
await MygigstersCard.init(config);- Returns:
Promise<void> - Throws: if
token,customerId,myGigsterId, orcontainerIdare missing; or if the container element is not found.
show()
Shows the card modal. Called automatically by init(), but can be called again after hide().
sdk.show();hide()
Hides the modal without destroying the SDK instance. The Airwallex card element state is preserved.
sdk.hide();setTheme(mode)
Switch the UI theme at runtime — no need to re-initialize.
sdk.setTheme('dark'); // or 'light'destroy()
Removes the modal from the DOM and resets all internal state. Call this when navigating away or unmounting the host component.
sdk.destroy();Success Response
The onSuccess callback receives a CardSuccessResponse object:
onSuccess: (res) => {
// res.paymentConsentId — Airwallex payment consent ID
// res.customerId — Customer ID associated with this consent
// res.myGigsterId — MyGigster ID associated with this consent
// res.timestamp — ISO-8601 timestamp of the save event
// res.event — 'card.saved'
console.log('Payment Consent ID:', res.paymentConsentId);
}Error Handling
Wrap init() in a try/catch to handle initialization errors:
try {
const sdk = new MygigstersCardSDK();
await sdk.init({
token: 'your_jwt_token',
customerId: 'cus_...',
myGigsterId: '4407c3ba-...',
containerId: 'mygigsters-card',
env: 'demo',
});
} catch (err) {
// Common errors:
// "token is required. Call GET /api/v1/client/me first..."
// "customerId is required"
// "myGigsterId is required"
// "Container element with ID '...' not found"
console.error('SDK failed to initialize:', err.message);
}Security
- Pre-fetched Token Auth — Clients authenticate with
GET /api/v1/client/meusing Basic Auth (apiKey:apiSecret) on their server or frontend to retrieve a JWT token. API credentials are never passed to or exposed inside the SDK. - Credentials are never stored in
localStorageorsessionStorage. - PCI-compliant card handling — Raw card data is handled exclusively by Airwallex's PCI-certified payment element embedded inside an Airwallex-controlled iframe.
- Shadow DOM (
mode: 'closed') prevents host-page scripts from reaching into the SDK's DOM.
TypeScript
Type definitions are included at dist/index.d.ts.
import { useEffect } from 'react';
import { MygigstersCardSDK } from '@mygigsters/card-sdk';
import type { MygigstersCardConfig, CardSuccessResponse } from '@mygigsters/card-sdk';
function SaveCardForm({ token, customerId, myGigsterId }: { token: string; customerId: string; myGigsterId: string }) {
useEffect(() => {
if (!token) return;
const config: MygigstersCardConfig = {
token,
customerId,
myGigsterId,
containerId: 'mygigsters-card',
env: 'demo',
mode: 'dark',
onSuccess: (res: CardSuccessResponse) => {
console.log('Card saved! Consent ID:', res.paymentConsentId);
},
onError: (err) => {
console.error('Card SDK error:', err);
},
};
const sdk = new MygigstersCardSDK();
sdk.init(config);
return () => sdk.destroy();
}, [token, customerId, myGigsterId]);
return <div id="mygigsters-card" />;
}
export default SaveCardForm;Changelog
1.0.3
- Added automatic identity verification step calling
profileDetailsAPI duringinit(). - Validates that
myGigsterIdreturned byprofileDetailsmatches themyGigsterIdpassed intoinit(). If it does not match, SDK initialization is blocked and an error is raised.
1.0.2
- Breaking Change: Updated authentication model to Pre-fetched Token (Flow B).
init()now acceptstoken(retrieved viaGET /api/v1/client/me) instead ofapiKey/apiSecret.- Updated TypeScript definitions and documentation.
1.0.0
- Initial public release.
License
MIT © MyGigsters
