@samveys/payment
From packages/payment/README.md in the framework repository.
One driver per payment gateway behind one contract: checkout(), status() and notification(). Drivers are built on @samveys/http-client and @samveys/webhooks.
| Driver | Checkout | Notifications |
|---|---|---|
midtrans({ serverKey }) | Snap (snap/v1/transactions) | signature_key (SHA-512 over order id, status code, amount and server key), verified over the raw body |
xendit({ secretKey, callbackToken }) | Invoice API (v2/invoices) | x-callback-token compared in constant time; the invoice is re-read before it is trusted |
Use it
import { midtrans } from '@samveys/payment'
const gateway = midtrans({ serverKey: process.env.MIDTRANS_SERVER_KEY! }) // SB-Mid-server-… selects the sandbox
const checkout = await gateway.checkout({
orderId: 'order-42',
amount: 150_000, // whole rupiah; must equal the item total when items are given
items: [{ id: 'sku-1', name: 'Report', price: 75_000, quantity: 2 }],
})
// Redirect the customer to checkout.redirectUrl.
router.post('/payments/midtrans', async (ctx) => {
const state = await gateway.notification(await ctx.request.text(), ctx.headers) // SVS_E108 when forged
if (state.status === 'settled') await markPaid(state.orderId, state.amount)
return new Response(null, { status: 204 })
})Statuses
Gateway statuses map to one set: pending, settled, failed, expired, cancelled, refunded, and challenge (Midtrans fraud review, settle it in the dashboard). Ask status(orderId) before you ship goods; never trust a notification body alone.
Testing
The test suite runs offline against the gateways' documented responses. Set MIDTRANS_SERVER_KEY to a sandbox key to also run the live sandbox test.