@govineer/payment-sdk
v1.0.257
Published
A modular, provider-agnostic payment processing SDK with support for multiple payment providers
Readme
@govineer/payment-sdk
A modular, processor-agnostic payment processing SDK. Zift is the implemented processor
today; the PaymentSDKBase abstraction exists so others (Square, Stripe, …) can be added
without changing integrator code.
Built with TypeScript for type safety and better developer experience.
📖 Full documentation → docs.govifi.io
Building a checkout UI? Prefer
@govineer/payment-component(or its Angular wrapper) — it renders card/ACH/Apple Pay entry with PAN capture isolated in a separate origin, and is documented in Embed the component. Use this SDK directly when you need the lower-level tokenization and Apple Pay primitives.
Installation
npm install @govineer/payment-sdkOr with yarn:
yarn add @govineer/payment-sdkQuick Start
TypeScript
import { ZiftPaymentSDK } from '@govineer/payment-sdk';
const sdk = new ZiftPaymentSDK({
paymentAccountUid: '12345678-1234-1234-1234-123456789abc', // Required
apiBaseUrl: 'https://your-api.com', //optional testing only
sandbox: true,
debug: true
});
await sdk.initialize();
if (sdk.isApplePayEnabled()) {
const result = await sdk.processApplePay(100.50);
console.log('Payment successful:', result.transactionId);
}JavaScript (ES Modules)
import { ZiftPaymentSDK } from '@govineer/payment-sdk';
const sdk = new ZiftPaymentSDK({
paymentAccountUid: '12345678-1234-1234-1234-123456789abc',
apiBaseUrl: 'https://your-api.com',//optional testing only
sandbox: true,
debug: true
});
await sdk.initialize();JavaScript (CommonJS)
const { ZiftPaymentSDK } = require('@govineer/payment-sdk');
const sdk = new ZiftPaymentSDK({
paymentAccountUid: '12345678-1234-1234-1234-123456789abc',
apiBaseUrl: 'https://your-api.com',
sandbox: true,
debug: true
});
await sdk.initialize();Architecture
The SDK is built with a base class (PaymentSDKBase) that defines a common interface for all payment processors.
PaymentSDKBase (Abstract)
↓
ZiftPaymentSDK
SquarePaymentSDK (future)
StripePaymentSDK (future)Features
- ✅ TypeScript - Full type safety and IntelliSense support
- ✅ Processor-Agnostic - Easy to switch between payment processors
- ✅ Apple Pay - Seamless Apple Pay integration
- ✅ Card Tokenization - Secure tokenization of payment methods
- ✅ Auto Token Refresh - Automatic credential refresh before tokenization
- ✅ Sandbox Mode - Test without real transactions
- ✅ Debug Mode - Detailed logging for troubleshooting
- ✅ Tree-Shakeable - Only bundle what you use
- ✅ Framework Agnostic - Works with React, Vue, Angular, vanilla JS
API Reference
ZiftPaymentSDK
Constructor
const sdk = new ZiftPaymentSDK({
paymentAccountUid: string; // Required: Payment account UID from your backend
apiBaseUrl: string; // Required: Your API base URL
sandbox?: boolean; // Enable sandbox mode (default: false)
debug?: boolean; // Enable debug logging (default: false)
});Methods
initialize()
Initialize the SDK. Must be called before any payment operations.
const result = await sdk.initialize();
// {
// success: boolean;
// processor: 'zift';
// applePayEnabled: boolean;
// }processApplePay(amount, callbacks?)
Process an Apple Pay payment.
const result = await sdk.processApplePay(100.50, {
beforeAuth: async (context) => {
// Optional: Calculate fees (currently disabled, returns 0)
const fees = await sdk.calculateFee(context.amount, 'R');
return {
amount: fees.totalAmount.toFixed(2),
customerEmail: '[email protected]'
};
},
afterAuth: async (context) => {
return {
invoiceNumber: 'INV-12345',
memo: 'Payment for services'
};
}
});tokenizeAccountNumber(accountNumber)
Tokenize a credit card or bank account number.
Note: The SDK automatically refreshes credentials before each tokenization attempt, as Zift proxynization tokens may expire after one use.
const result = await sdk.tokenizeAccountNumber('4111111111111111');
// {
// processor: 'zift';
// accountNumber: 'token_here';
// responseCode: 'A01';
// responseMessage: 'Approved';
// }calculateFee(amount, accountType)
Calculate payment processing fees.
Important: This method is currently disabled and returns placeholder values with zero fees. Fee calculation will need to be implemented in the future based on actual processor rates and business requirements.
const fees = await sdk.calculateFee(100.00, 'R');
// {
// processor: 'zift';
// amount: 100.00;
// convenienceFee: 0; // TODO: Implement actual fee calculation
// developerFee: 0; // TODO: Implement actual fee calculation
// totalAmount: 100.00;
// }refreshToken()
Manually refresh client configuration (credentials, tokens). This is automatically called before each tokenization.
await sdk.refreshToken();Static Methods
ZiftPaymentSDK.getAccountTypes()
Get Zift account type constants.
const types = ZiftPaymentSDK.getAccountTypes();
// {
// CREDIT_CARD: 'R',
// CHECKING: 'C',
// SAVINGS: 'S'
// }ZiftPaymentSDK.getResponseCodeDescription(code)
Get human-readable description for response codes.
const desc = ZiftPaymentSDK.getResponseCodeDescription('A01');
// 'Approved'Usage Examples
Complete Payment Flow
import { ZiftPaymentSDK } from '@govineer/payment-sdk';
async function processPayment(amount: number) {
// Initialize SDK
const sdk = new ZiftPaymentSDK({
paymentAccountUid: '12345678-1234-1234-1234-123456789abc',
apiBaseUrl: 'https://your-api.com',
sandbox: true,
debug: process.env.NODE_ENV === 'development'
});
await sdk.initialize();
// Check Apple Pay availability
if (!sdk.isApplePayEnabled()) {
throw new Error('Apple Pay not available');
}
// Process payment
const result = await sdk.processApplePay(amount, {
beforeAuth: async (context) => {
return {
amount: amount.toFixed(2),
customerEmail: '[email protected]'
};
},
afterAuth: async (context) => {
return {
invoiceNumber: `INV-${Date.now()}`,
memo: 'Online payment'
};
}
});
if (result.success) {
console.log('Payment successful!', result.transactionId);
return result;
} else {
throw new Error(result.error || 'Payment failed');
}
}Card Tokenization
import { ZiftPaymentSDK } from '@govineer/payment-sdk';
async function savePaymentMethod(cardNumber: string) {
const sdk = new ZiftPaymentSDK({
paymentAccountUid: '12345678-1234-1234-1234-123456789abc',
apiBaseUrl: 'https://your-api.com',
sandbox: true
});
await sdk.initialize();
// SDK automatically refreshes token before tokenization
const result = await sdk.tokenizeAccountNumber(cardNumber);
if (result.responseCode === 'A01') {
// Save token to your backend
await saveToBackend({
token: result.accountNumber,
last4: cardNumber.slice(-4)
});
return result.accountNumber;
} else {
throw new Error(result.responseMessage);
}
}React Hook Example
import { useState, useEffect } from 'react';
import { ZiftPaymentSDK } from '@govineer/payment-sdk';
function usePaymentSDK(paymentAccountUid: string) {
const [sdk, setSDK] = useState<ZiftPaymentSDK | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
async function init() {
try {
const paymentSDK = new ZiftPaymentSDK({
paymentAccountUid: paymentAccountUid,
apiBaseUrl: process.env.REACT_APP_API_URL || 'http://localhost:5000',
sandbox: true,
debug: process.env.NODE_ENV === 'development'
});
await paymentSDK.initialize();
setSDK(paymentSDK);
} catch (err) {
setError(err as Error);
} finally {
setLoading(false);
}
}
init();
}, [paymentAccountUid]);
return { sdk, loading, error };
}
export default usePaymentSDK;Configuration
Development
For local development, point to your local API:
const sdk = new ZiftPaymentSDK({
paymentAccountUid: '12345678-1234-1234-1234-123456789abc',
apiBaseUrl: 'http://localhost:5000',
sandbox: true,
debug: true
});Production
For production deployments:
const sdk = new ZiftPaymentSDK({
paymentAccountUid: '12345678-1234-1234-1234-123456789abc',
apiBaseUrl: 'https://api.yourcompany.com',
sandbox: false,
debug: false
});Backend Requirements
Your backend must implement the unified client configuration endpoint:
GET /api/paymentaccounts/{uid}/client-config?sandbox={bool}
Returns processor-specific client configuration including temporary credentials.
Request:
GET /api/paymentaccounts/12345678-1234-1234-1234-123456789abc/client-config?sandbox=trueResponse:
{
"processor": "zift",
"config": {
"temporary_password": "temp_xyz123",
"account_id": "6659001",
"api_key": "base64_encoded_key",
"expiration_date": "2024-11-04T12:00:00Z"
},
"supported_methods": ["apple_pay", "credit_card"]
}Field Descriptions:
processor- Processor type (zift, square, stripe, etc.)config.temporary_password- Proxynization token for card tokenizationconfig.account_id- Processor account ID (used as username for tokenization)config.api_key- Base64-encoded API credentials for Apple Payconfig.expiration_date- When these credentials expire (ISO 8601)supported_methods- Array of supported payment methods
Note: The SDK automatically calls this endpoint during initialization and before each tokenization attempt to refresh credentials.
Testing & development
This package lives in the Govifi payment monorepo (pnpm workspace). To work on it:
corepack pnpm install --frozen-lockfile
corepack pnpm --filter @govineer/payment-sdk build # or: dev (watch)
corepack pnpm --filter @govineer/payment-sdk testTwo browser test pages live alongside the source for manual checks: test.html (loads the
built dist/ output) and test-standalone.html (SDK inlined, no build step). Point either
at a local API (docker-compose up -d, http://localhost:5000), paste a payment-account
uid, enable sandbox, and tokenize 4111111111111111. These pages are not part of the
published package.
Releases are built and published by the Azure DevOps pipeline — there are no version-bump or publish commands to run by hand.
Browser Support
- Modern browsers with ES2020+ support
- Safari 11+ (for Apple Pay)
- Chrome 80+
- Firefox 80+
- Edge 80+
TypeScript Support
This package is written in TypeScript and includes type definitions. No additional @types package is needed.
import { ZiftPaymentSDK, PaymentResult, TokenizationResult } from '@govineer/payment-sdk';
const sdk: ZiftPaymentSDK = new ZiftPaymentSDK({
paymentAccountUid: '12345678-1234-1234-1234-123456789abc',
apiBaseUrl: 'https://your-api.com',
sandbox: true
});
const result: PaymentResult = await sdk.processApplePay(100.00);
const tokenResult: TokenizationResult = await sdk.tokenizeAccountNumber('4111111111111111');Key Differences from Previous Versions
Unified Endpoint
Previous versions required separate endpoints for different credential types. The new version uses a single unified endpoint:
Old:
POST /api/zift/proxynization-token
POST /api/zift/api-tokenNew:
GET /api/paymentaccounts/{uid}/client-config?sandbox={bool}Automatic Token Refresh
The SDK now automatically refreshes credentials before each tokenization attempt, eliminating authentication failures from expired tokens.
Payment Account UID
The SDK now requires a payment account UID instead of relying on hardcoded processor credentials. This allows for multi-tenant deployments where each client has their own payment account.
Troubleshooting
"Failed to initialize Zift SDK"
Check that:
- Your API is running and accessible
- The
paymentAccountUidis correct - The payment account exists in your database and is active
- CORS is properly configured on your API
"Apple Pay not available"
Apple Pay requires:
- Safari browser on macOS or iOS
- Device with Apple Pay capability
- Valid payment cards added to Apple Wallet
- HTTPS connection (except localhost)
Tokenization Authentication Errors
If you see "Username or password is invalid":
- Check that the payment account has a valid
external_account_id - Verify Zift credentials are correct in your API configuration
- Ensure the account ID matches your Zift account
- The SDK automatically refreshes tokens, so this should be rare
CORS Errors
If you see CORS errors in the browser console:
- Ensure your API has CORS enabled
- Check that the API URL is correct
- Verify the API is returning proper CORS headers
License
MIT © Caselle
Support
Questions or bug reports: [email protected]
