Core JavaScript SDK for Tagada Pay with provider-agnostic tokenization, 3DS, and React hooks
npm install @tagadapay/core-jsProvider-agnostic payment tokenization and 3DS authentication SDK for TagadaPay.
- ✅ Provider-Agnostic: Works with BasisTheory, Stripe, Adyen, or any tokenization provider
- ✅ TagadaToken: Automatic creation of TagadaPay's standard token format
- ✅ 3DS Authentication: Complete 3DS flow with session management and challenge handling
- ✅ SCA Detection: Automatic detection of Strong Customer Authentication requirements
- ✅ React Hooks: Optional React integration with useCardTokenization and useThreeds
- ✅ Framework Agnostic: Core functionality works in any JavaScript environment
- ✅ TypeScript: Full type safety and IntelliSense support
``bash`
npm install @tagadapay/core-jsor
pnpm install @tagadapay/core-js
Get your TagadaPay API keys from: https://app.tagadapay.com/settings/apiKeys
You'll need these for backend operations (payment processing, payment instrument creation, etc.). Card tokenization happens client-side and doesn't require API keys.
`typescript
import { useCardTokenization } from '@tagadapay/core-js/react';
function CheckoutForm() {
const { tokenizeCard, isLoading, error } = useCardTokenization({
environment: 'production',
autoInitialize: true,
});
const handleSubmit = async (cardData) => {
// Get TagadaToken (ready for backend) and rawToken (for UI)
const { tagadaToken, rawToken } = await tokenizeCard(cardData);
// Check if 3DS is required (provider-agnostic!)
if (rawToken.metadata?.auth?.scaRequired) {
console.log('3DS authentication required');
}
// Send to your backend
await fetch('/api/payment-instruments/create', {
method: 'POST',
body: JSON.stringify({ tagadaToken, storeId, customerData }),
});
};
return
;$3
`typescript
import { Tokenizer, createTagadaToken } from '@tagadapay/core-js';const tokenizer = new Tokenizer({ environment: 'production' });
await tokenizer.initialize();
// Returns TagadaToken string
const tagadaToken = await tokenizer.tokenizeCard(cardData);
// Or get normalized response
const rawToken = await tokenizer.tokenizeCardRaw(cardData);
const tagadaToken = createTagadaToken(rawToken);
`Core Concepts
$3
TagadaPay's standard token format that wraps provider-specific tokens:
`json
{
"type": "card",
"token": "provider_token_id",
"provider": "basistheory",
"nonSensitiveMetadata": {
"authentication": "sca_required",
"last4": "4242",
"bin": "424242",
"brand": "visa",
"expiryMonth": 12,
"expiryYear": 2026
}
}
`$3
`typescript
const { rawToken } = await tokenizeCard(cardData);// Works with ANY provider (BasisTheory, Stripe, Adyen, etc.)
if (rawToken.metadata?.auth?.scaRequired) {
// Handle 3DS authentication
}
`$3
Use the default provider (BasisTheory):
`typescript
const tokenizer = new Tokenizer();
`Or use a custom provider:
`typescript
import { Tokenizer, StripeProvider } from '@tagadapay/core-js';const tokenizer = new Tokenizer({
provider: new StripeProvider({ apiKey: 'pk_...' }),
});
`API Reference
$3
`typescript
interface TokenizeCardResult {
tagadaToken: string; // Base64-encoded TagadaToken (send to backend)
rawToken: CardTokenResponse; // Normalized token (for UI/SCA checking)
}const {
tokenizeCard: (cardData: CardPaymentMethod) => Promise,
tokenizeApplePay: (applePayToken: ApplePayToken) => Promise,
tokenizeGooglePay: (googlePayToken: GooglePayToken) => Promise,
initialize: () => Promise,
isLoading: boolean,
isInitialized: boolean,
error: string | null,
clearError: () => void,
} = useCardTokenization(config);
`$3
`typescript
class Tokenizer {
constructor(config: PaymentSDKConfig & { provider?: ITokenizationProvider }); // Returns TagadaToken string (ready for backend)
async tokenizeCard(cardData: CardPaymentMethod): Promise;
// Returns normalized CardTokenResponse (for advanced usage)
async tokenizeCardRaw(cardData: CardPaymentMethod): Promise;
async tokenizeApplePay(applePayToken: ApplePayToken): Promise;
async tokenizeGooglePay(googlePayToken: GooglePayToken): Promise;
async initialize(): Promise;
isReady(): boolean;
getProvider(): ITokenizationProvider;
}
`$3
`typescript
// Create TagadaToken from normalized response
function createTagadaToken(cardTokenResponse: CardTokenResponse, providerName?: string): string;// Decode TagadaToken
function decodeTagadaToken(tagadaTokenString: string): TagadaToken;
`$3
`typescript
// Get tenant ID for Google Pay configuration
import { getGoogleTenantId } from '@tagadapay/core-js';const tenantId = getGoogleTenantId('development'); // or 'production', 'local'
// Use in Google Pay configuration
const paymentRequest = {
// ... other config
allowedPaymentMethods: [{
tokenizationSpecification: {
type: 'PAYMENT_GATEWAY',
parameters: {
gateway: 'basistheory',
gatewayMerchantId: tenantId,
},
},
}],
};
`$3
`typescript
const {
createSession: (instrument, options) => Promise,
startChallenge: (challenge, options?) => Promise,
isLoading: boolean,
error: ThreedsError | null,
} = useThreeds({
environment: 'production',
autoInitialize: true,
});
`$3
`typescript
import { ThreedsManager } from '@tagadapay/core-js/threeds';const manager = new ThreedsManager({
defaultProvider: 'basis_theory',
providers: {
basis_theory: { apiKey: 'your-api-key' },
},
});
const session = await manager.createSession(paymentInstrument, options);
const completion = await manager.startChallenge(challenge);
`Complete Example
`typescript
import { useCardTokenization, useThreeds } from '@tagadapay/core-js/react';function PaymentFlow() {
// 1. Tokenization
const { tokenizeCard } = useCardTokenization({
environment: 'production',
});
// 2. 3DS
const { createSession, startChallenge } = useThreeds({
environment: 'production',
});
const handlePayment = async (cardData) => {
// Step 1: Tokenize card
const { tagadaToken, rawToken } = await tokenizeCard(cardData);
// Step 2: Create payment instrument (server-side)
const { paymentInstrument } = await fetch('/api/payment-instruments/create', {
method: 'POST',
body: JSON.stringify({ tagadaToken, storeId, customerData }),
}).then((r) => r.json());
// Step 3: Create 3DS session (if SCA required)
if (rawToken.metadata?.auth?.scaRequired) {
const session = await createSession(
{
id: paymentInstrument.id,
token: rawToken.id,
type: 'card',
card: {
expirationMonth: rawToken.data.expiration_month,
expirationYear: rawToken.data.expiration_year,
last4: rawToken.data.number?.slice(-4),
},
},
{
amount: 2999,
currency: 'USD',
customerInfo: { name: 'John Doe', email: 'john@example.com' },
},
);
// Persist session to backend
await fetch('/api/threeds/sessions', {
method: 'POST',
body: JSON.stringify({
provider: session.provider,
storeId,
paymentInstrumentId: paymentInstrument.id,
sessionData: session.metadata?.raw,
}),
});
}
// Step 4: Process payment (server-side)
const { payment } = await fetch('/api/payments/process', {
method: 'POST',
body: JSON.stringify({
amount: 2999,
currency: 'USD',
storeId,
paymentInstrumentId: paymentInstrument.id,
}),
}).then((r) => r.json());
// Step 5: Handle 3DS challenge if required (client-side)
if (payment.requireAction === 'threeds_auth') {
const { threedsSession } = payment.requireActionData.metadata;
await startChallenge({
sessionId: threedsSession.externalSessionId,
acsChallengeUrl: threedsSession.acsChallengeUrl,
acsTransactionId: threedsSession.acsTransID,
threeDSVersion: threedsSession.messageVersion,
});
// Poll for final payment status
const finalPayment = await pollPaymentStatus(payment.id);
console.log('Payment status:', finalPayment.status);
}
};
}
`Exports
$3
`typescript
import {
// Classes
Tokenizer, // Types
CardTokenResponse,
CardPaymentMethod,
ApplePayToken,
GooglePayToken,
PaymentSDKConfig,
// TagadaToken
createTagadaToken,
decodeTagadaToken,
TagadaToken,
// Providers
ITokenizationProvider,
BasisTheoryProvider,
// Configuration
getGoogleTenantId,
} from '@tagadapay/core-js';
`$3
`typescript
import { useCardTokenization, useThreeds, TokenizeCardResult } from '@tagadapay/core-js/react';
`$3
`typescript
import {
ThreedsManager,
ThreedsModal,
ThreedsSession,
ThreedsChallenge,
ChallengeCompletion,
ThreedsError,
ThreedsErrorCode,
} from '@tagadapay/core-js/threeds';
`Adding Custom Providers
`typescript
import { ITokenizationProvider, RawTokenResponse } from '@tagadapay/core-js';export class StripeProvider implements ITokenizationProvider {
private stripe: any;
private config: { apiKey: string };
constructor(config: { apiKey: string }) {
this.config = config;
}
getProviderName(): string {
return 'Stripe';
}
async initialize(): Promise {
this.stripe = await loadStripe(this.config.apiKey);
}
isInitialized(): boolean {
return !!this.stripe;
}
async tokenizeCard(cardData: CardPaymentMethod): Promise {
const token = await this.stripe.createToken('card', {
number: cardData.cardNumber,
exp_month: / ... /,
exp_year: / ... /,
cvc: cardData.cvc,
});
return token as RawTokenResponse;
}
async tokenizeApplePay(applePayToken: ApplePayToken): Promise {
// Stripe Apple Pay implementation
}
detectScaRequirement(rawResponse: RawTokenResponse): boolean {
// Stripe-specific SCA detection
return rawResponse.card?.three_d_secure_usage?.supported === true;
}
}
// Use it
const tokenizer = new Tokenizer({
provider: new StripeProvider({ apiKey: 'pk_...' }),
});
`Environment Configuration
The SDK automatically selects the correct BasisTheory API key based on environment:
`typescript
// Production
useCardTokenization({ environment: 'production' });
// Uses: process.env.NEXT_PUBLIC_BASIS_THEORY_PUBLIC_API_KEY or embedded prod key// Development/Local
useCardTokenization({ environment: 'development' });
// Uses: Embedded test key (safe for local dev)
`Examples
See the complete working examples:
$3
- Card tokenization with TagadaToken creation
- SCA requirement detection
- Payment instrument creation
- 3DS session management
- Payment processing with 3DS
- Retry 3DS flow
- Backend/frontend separation best practices$3
- Apple Pay tokenization
- Google Pay tokenization with tenant ID configuration
- Real TagadaPay API integration
- Step-by-step payment flowTypeScript
The SDK is written in TypeScript and provides full type definitions:
`typescript
import type {
CardTokenResponse,
TagadaToken,
ThreedsSession,
ThreedsChallenge,
TokenizeCardResult,
} from '@tagadapay/core-js';
``- Modern browsers (ES2020+)
- React 18+
- TypeScript 5+
MIT
- GitHub: tagadapay/tagadapay
- Documentation: docs.tagadapay.com
- Issues: GitHub Issues