Go Live
Before switching your integration to production, work through this checklist. Each item maps to a real failure mode — a missed step means either lost revenue or silent data corruption in production.
Checklist
1. Switch environment to production
Set environment: 'production' in both SDKs.
Node SDK:
import AccruPay from '@accrupay/node';
const sdk = new AccruPay({
apiSecret: process.env.ACCRUPAY_API_SECRET,
environment: 'production',
});
React SDK:
<AccruPay
merchantPublicId={process.env.NEXT_PUBLIC_ACCRUPAY_MERCHANT_PUBLIC_ID}
transactionSessionId={sessionId}
environment="production"
>
{/* payment fields */}
</AccruPay>
The default is production, but set it explicitly so it is visible in code review.
2. Use production API credentials
Load secrets from environment variables. Never hardcode them.
// Good
const sdk = new AccruPay({
apiSecret: process.env.ACCRUPAY_API_SECRET,
});
// Bad — do not do this
const sdk = new AccruPay({
apiSecret: 'sk_live_abc123...',
});
Replace your sandbox API Secret with the production key from Settings → API Keys in the AccruPay dashboard. Do the same for every connected provider's credentials under Settings → Payment Providers.
3. Configure provider webhooks
Each connected payment provider needs to deliver webhook events back to AccruPay so that transaction status stays in sync.
- Open Settings → Payment Providers in the AccruPay dashboard.
- Copy the webhook URL shown for each provider.
- Go to that provider's dashboard and register the URL as a webhook endpoint.
- Enable the event types AccruPay requires (listed on the same settings page).
Do this for every provider you have active — an unconfigured webhook means delayed or missed transaction status updates.
4. Always call verify() server-side
The frontend callback is informational only. The authoritative result comes from your backend calling verify() after the customer submits payment.
// Called from your backend — not from the browser
const transaction = await sdk.transactions.clientSessions.payments.verify({
merchantInternalTransactionCode: order.id, // use same code passed to start()
});
if (transaction.status !== 'SUCCEEDED') {
// handle decline or error
}
Never fulfill an order based on a frontend success callback alone.
5. Set merchantInternalTransactionCode on every start()
This is your idempotency key. AccruPay uses it to match sessions to your internal order records and to safely recover from network errors or duplicate submissions.
const session = await sdk.transactions.clientSessions.payments.start({
merchantTransactionProviderId: process.env.ACCRUPAY_PROVIDER_ID,
data: {
amount: 10000n,
currency: CURRENCY.USD,
merchantInternalTransactionCode: order.id, // unique per order
merchantInternalCustomerCode: customer.id,
// ...
},
});
Use a value that is unique per transaction and stable across retries — your internal order ID is the right choice.
6. Wire error callbacks
Configure all three error callbacks on the Node SDK so your alerting system catches authentication failures, GraphQL errors, and network issues:
const sdk = new AccruPay({
apiSecret: process.env.ACCRUPAY_API_SECRET,
environment: 'production',
onAuthError: () => {
alerting.critical('AccruPay authentication failed');
},
onGraphQLError: errors => {
alerting.error('AccruPay GraphQL error', { errors });
},
onNetworkError: error => {
alerting.error('AccruPay network error', { error });
},
});
Silent failures in a payment backend are expensive. These callbacks are the earliest signal.
7. Remove test payment details from code
Audit your codebase for hardcoded test card numbers, test CVCs, and test billing addresses. None of these should exist in production code.
# Quick audit
grep -r "4111\|4242\|test@" src/
Test card numbers in your source code often end up in logs or analytics events, which creates compliance exposure.
8. Update Content Security Policy headers
If your app sends a Content-Security-Policy header, add the origins for each payment provider you have configured. A missing entry blocks the payment form from rendering — no error is shown to the customer.
script-src 'self' https://cdn.safecharge.com;
frame-src 'self' https://cdn.safecharge.com;
script-src 'self' https://js.stripe.com;
frame-src 'self' https://js.stripe.com;
connect-src 'self' https://api.stripe.com;
Consult your provider's integration documentation for the CDN origins to add. Find the exact domains in the Provider Integrations section for each provider you have configured.
Run your full payment flow end-to-end with a small real transaction before announcing to users. Confirm that verify() returns SUCCEEDED, your order fulfillment logic fires, and your webhook handler receives and processes the provider event.
Next steps
- the Provider Integrations section in the sidebar
- Error Handling
- Card Checkout Guide