Refund
Return captured funds fully or partially, and track refund status through to the customer.
A refund returns captured funds to the customer on the same rail as the original payment. Refunds are asynchronous objects with their own lifecycle and dedicated events — you never need to poll for the outcome.
To void an authorization before any funds are captured, use Cancel. To undo a captured payment on the same business day before settlement, use Reverse.
Create a refundAsk
Refund a payment by its ID. Without an amount, VINR refunds the full remaining refundable balance.
import { Vinr } from '@vinr/sdk';
const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });
const refund = await vinr.refunds.create({
payment: 'pay_3Nf8x2a',
reason: 'requested_by_customer',
metadata: { ticketId: 'ZD-4821' },
});
// refund.id → "re_7Qp2m1c..."
// refund.status → "pending"
// refund.amount → 5000 (full original amount)curl -X POST https://api.vinr.com/v1/refunds \
-H "X-Api-Key: $VINR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{ "payment": "pay_3Nf8x2a", "reason": "requested_by_customer" }'Prop
Type
Partial refundsAsk
Pass an explicit amount to refund only part of the captured total. The same payment can be refunded multiple times until the refundable balance reaches zero.
// €50.00 charge — refund €10.00
const partial = await vinr.refunds.create({
payment: 'pay_3Nf8x2a',
amount: 1000,
reason: 'product_not_received',
});Once amountRefunded equals the captured amount the payment moves to refunded. While a balance remains, the status is partially_refunded. Requesting more than the remaining balance returns 422 with code amount_too_large.
Refund status and timingAsk
| Status | Meaning |
|---|---|
pending | Accepted by VINR, queued to the rail. |
succeeded | Funds confirmed on their way to the customer. |
failed | Rejected — see Refund failure reasons. |
cancelled | Withdrawn before reaching the rail. |
Settlement time is controlled by the customer's card issuer or bank:
| Rail | Typical time to customer |
|---|---|
| Cards | 5–10 business days |
| SEPA / bank transfer | 1–3 business days |
| Stablecoins | Minutes after on-chain confirmation |
Subscribe to events rather than polling:
const event = vinr.webhooks.verify(rawBody, req.headers['x-vinr-signature']);
if (event.type === 'refund.succeeded') {
const refund = event.data;
await markOrderRefunded(refund.metadata.ticketId, refund.amount);
}Relevant events: refund.created, refund.succeeded, refund.failed. See Webhooks for setup and signature verification.
FeesAsk
Processing fees on the original charge are not returned when you issue a refund — this mirrors card scheme rules. The refunded principal is debited from your VINR balance; if insufficient, the shortfall is recovered from your next settlement.
Refunding more than your available balance pushes it negative and can delay the next payout. Maintain a buffer if you process high refund volume.
Next stepsAsk
Refund failure reasons
Why a refund can fail and what to do in each case.
Reverse
Same-day undo of a captured payment before it settles.
Disputes
When a customer reverses a payment through their bank.
Last updated on