Quickstart
A complete server-to-frontend integration: create a payment session on your backend, render the checkout on your frontend, verify the result on your backend.
1. Initialize the Node SDK
On your server, instantiate the client once at startup:
import AccruPay, { TRANSACTION_PROVIDER, CURRENCY, COUNTRY_ISO_2 } from '@accrupay/node';
const sdk = new AccruPay({
apiSecret: process.env.ACCRUPAY_API_SECRET,
// environment defaults to 'production'
// set environment: 'qa' for sandbox testing — see Sandbox guide
});
Store ACCRUPAY_API_SECRET in your environment and never hard-code it. A single sdk instance is safe to reuse across requests.
2. Start a payment session (server)
Call this from a backend route — for example, when a customer reaches your checkout page.
const session = await sdk.transactions.clientSessions.payments.start({
merchantTransactionProviderId: process.env.ACCRUPAY_PROVIDER_ID, // UUID of your connected provider account
data: {
// Your internal order/idempotency key — used again in verify()
merchantInternalTransactionCode: 'order_123',
amount: 10000n, // BigInt, in minor units — 10000n = $100.00 USD
currency: CURRENCY.USD,
storePaymentMethod: false,
customer: {
merchantInternalCustomerCode: 'customer_abc',
},
billing: {
billingFirstName: 'Jane',
billingLastName: 'Doe',
billingEmail: 'jane@example.com',
billingAddressCountry: COUNTRY_ISO_2.US,
},
},
});
// Return only session.id to your frontend — never the full session object or your apiSecret
return res.json({ sessionId: session.id });
AccruPay amounts are always integers in minor currency units. For USD: 10000n = $100.00, 999n = $9.99. Use BigInt literals (the n suffix) — do not pass plain numbers.
3. Render the checkout (frontend)
Use session.id from your backend response to initialize the React SDK:
import {
AccruPay,
CardholderName,
CardNumber,
CardExpiry,
CardCVC,
SubmitButton,
} from '@accrupay/react';
interface CheckoutProps {
sessionId: string; // session.id from your backend
}
export function Checkout({ sessionId }: CheckoutProps) {
return (
<AccruPay
merchantPublicId={process.env.NEXT_PUBLIC_ACCRUPAY_MERCHANT_ID}
transactionSessionId={sessionId}
>
<CardholderName />
<CardNumber />
<CardExpiry />
<CardCVC />
<SubmitButton>Pay now</SubmitButton>
</AccruPay>
);
}
When the customer submits the form, the React SDK handles the provider-side payment step without exposing your API secret.
4. Verify the payment (server)
After the frontend signals completion, verify the result server-side using the same merchantInternalTransactionCode you passed to start():
const transaction = await sdk.transactions.clientSessions.payments.verify({
merchantInternalTransactionCode: 'order_123',
});
switch (transaction.status) {
case 'SUCCEEDED':
// Safe to fulfill the order
await fulfillOrder('order_123');
break;
case 'DECLINED':
case 'FAILED':
// Inform the customer — the payment did not go through
break;
case 'PENDING':
// Payment is still processing — poll or wait for a webhook
break;
default:
// Handle EXPIRED, CANCELED, ERROR, UNKNOWN as appropriate
break;
}
Never trust the frontend to confirm payment success. The only authoritative result is the status returned by verify() on your server. A frontend callback can be spoofed or interrupted.
Transaction status reference
| Status | Meaning |
|---|---|
SUCCEEDED | Payment captured — safe to fulfill |
PENDING | Processing in progress — do not fulfill yet |
DECLINED | Issuer declined the payment |
FAILED | Technical failure during processing |
EXPIRED | Session timed out before the customer completed payment |
CANCELED | Payment canceled by the customer or merchant |
ERROR | Unexpected error — check logs |
UNKNOWN | Status cannot be determined — investigate before fulfilling |
Next steps
- Sandbox — run end-to-end tests without real charges
- Card Checkout Guide — detailed flow diagrams and edge cases
- Node SDK Reference — full SDK method reference
- API Reference — raw GraphQL operations