Refunds and disputes

Send money back to a customer with a refund, and answer the bank when a customer disputes a charge.

Refund a payment

A refund returns all or part of a succeeded payment to the card or bank account it was paid with. You can refund a payment more than once, up to the amount collected.

In the dashboard, open the payment, click Actions, then Refund. Amount starts at everything left to refund. Lower it for a partial refund, then click Issue refund (or Refund $X.XX for a partial amount).

The Refund dialog on a payment

With the API, create a refund for the payment. Leave out amount to refund everything that’s left:

server.ts

const refund = await bias.refunds.create({
    payment: "pay_5qRDCgiIwaqIOrRZRpGY2",
    amount: 1500,
});

Only succeeded payments can be refunded. To release a card payment you haven’t captured yet, cancel it instead.

Refund status

A refund starts as pending and becomes succeeded or failed. A bank account refund stays pending until the bank confirms it. If a refund fails, the reason is in its failed_reason, and the amount can be refunded again. Bias sends refund.created, then refund.succeeded or refund.failed.

The payment’s amount_refunded includes pending and succeeded refunds. In the dashboard, the payment shows Partially refunded or Refunded, and each refund appears in its timeline.

A payment with an open or lost chargeback, or whose bank debit was returned, can’t be refunded. If you win the chargeback, the payment can be refunded.

Disputes

A dispute opens when a customer questions a card payment with their bank. It’s one of two kinds, in payment_method_details.card.case_type:

  • An inquiry is a request for you to provide information about the charge. The payment can still be refunded.
  • A chargeback is a request to the bank to reverse the payment.

You can answer either kind with evidence.

Bias sends dispute.created and dispute.updated. To get an email when a chargeback or inquiry is opened or resolved, turn on Disputes under Notifications in Settings → Profile.

In the dashboard, filter the Payments tab by Disputed to see every disputed payment. Open one to see its dispute, respond to it, or accept the loss.

Dispute status

StatusMeaning
needs_responseThe bank is waiting for your response, due by evidence_details.due_by.
under_reviewThe bank is reviewing the dispute.
wonThe bank decided in your favor.
lostThe bank decided in the customer’s favor.

Respond with evidence

Responses are due by evidence_details.due_by. Evidence is a set of fields on the dispute, such as a product description, shipping details and receipts. Save it with update a dispute as you gather it, then send it with submit: true. Once you submit, the dispute moves to under_review and its evidence can’t change. After the deadline, evidence can’t be submitted.

Upload documents as files with the purpose dispute_evidence, then attach them by ID. Evidence files must be PDF, JPEG, PNG or plain text.

server.ts

const receipt = await bias.files.create({
    file: new File([receiptPdf], "receipt.pdf", { type: "application/pdf" }),
    purpose: "dispute_evidence",
});
if (receipt.object === "error") throw new Error(receipt.error.message);

const dispute = await bias.disputes.update("du_9Ds1dub2oH1ePmx5TpGY2", {
    evidence: {
        product_description: "Snowboard bindings, size M",
        receipt: receipt.id,
        shipping_tracking_number: "1Z12345E0205271688",
    },
    submit: true,
});

Accept the loss

If you won’t contest a dispute, accept the loss with loss_accepted: true. You can do this while the dispute is needs_response or under_review, and undo it with false while it’s still open. Evidence can’t be submitted for a dispute with an accepted loss. Its status still changes to won or lost when the bank decides, and the dashboard shows Loss accepted until then.

Bank returns

When a customer’s bank returns a bank account debit after it succeeded, Bias records the returned amount as a dispute. Its payment_method_details.type is us_bank_account, with the bank’s return code in us_bank_account.return_code. A bank return is created lost and can’t be contested, so no evidence can be submitted.

To create disputes in a sandbox, use the dispute test cards. The test bank accounts include ones that are returned after they succeed.