Mintcash
Guides

Issue a refund

Refund a successful payment in full or in part. Multiple partial refunds are allowed up to the original amount.

Refunds return money to the customer's card. You can refund a payment in full once, or in several partial refunds that sum up to the original amount. Each refund is its own resource you can look up by ID.

Eligible payments

A payment can be refunded only if it's in succeeded or partially_refunded. Refunds against failed, voided, or already-fully-refunded payments are rejected.

Issuing a refund

Full refund

Send amount: null (or omit it) to refund the entire remaining amount:

await fetch(
  `https://sandbox.mintcash.me/payments/${paymentId}/refund`,
  {
    method: "POST",
    headers: { Authorization: ..., "Content-Type": "application/json" },
    body: JSON.stringify({
      externalId: `refund_${orderId}_full`,
      reason: "customer_request",
    }),
  },
);

The payment transitions to refunded (terminal).

Partial refund

Specify an amount less than the remaining refundable balance:

await fetch(
  `https://sandbox.mintcash.me/payments/${paymentId}/refund`,
  {
    method: "POST",
    headers: { Authorization: ..., "Content-Type": "application/json" },
    body: JSON.stringify({
      externalId: `refund_${orderId}_partial_1`,
      amount: 1500,                    // $15.00 of a $49.99 payment
      reason: "item_returned",
    }),
  },
);

The payment transitions to partially_refunded. The remaining refundable amount is on the payment response as amountRefundable.

State diagram

Rendering diagram…

What you receive

When a refund processes, you get one of two webhooks:

EventWhen
payment.partially_refundedRefund succeeded; more refunds still possible
payment.refundedRefund cleared the remaining balance — terminal
payment.refund_failedThe refund attempt failed; payment is unchanged

Webhook data includes both the parent payment and the new refund record.

Idempotency

externalId on POST /refund is required and scoped per payment. Two refunds against the same payment can't share an externalId. A retry with the same externalId returns the existing refund record without issuing a duplicate.

Refunds settle on the provider's clock

We tell the provider to refund immediately. The actual money on the customer's card can take 3–10 business days depending on issuer. Set customer expectations accordingly, especially during chargeback disputes.

Listing refunds for a payment

const refunds = await fetch(
  `https://sandbox.mintcash.me/payments/${paymentId}/refunds`,
  { headers: { Authorization: ... } },
).then((r) => r.json());

for (const r of refunds) {
  console.log(r.id, r.amount, r.status, r.createdAt);
}

Or retrieve a single refund by its own ID:

await fetch(`https://sandbox.mintcash.me/refunds/${refundId}`, ...);

What to test

  • Full refund — payment.refunded arrives; further refund attempts fail
  • Two partial refunds totalling less than the payment — payment stays in partially_refunded
  • Final partial refund that clears the balance — payment.refunded
  • Refund against a failed payment — 400 invalid_argument
  • Duplicate refund externalId — second call returns the original refund