Developers Guides Refund an Order

Refund an Order

Process a full refund by creating a return order with negative quantities. Covers the complete refund flow with API examples and payment method requirements.

Online API Payments Refunds In-Store

Overview

A full refund in Surfboard is processed by creating a new order with negative quantities and negative amounts, referencing the original order’s orderId as the purchaseOrderId on each line item. When the payment completes, the full amount is returned to the customer.

When to Use Full Refund

ScenarioDescription
Product returnCustomer returns all items
Service not deliveredFull service cancellation
Order errorWrong order fulfilled entirely
Post-settlement reversalPayment already settled, void no longer possible

If the payment hasn’t settled yet (same day, before 23:00 UTC), consider using Void a Payment instead — it’s faster and avoids refund processing fees.

Step 1: Create a Refund Order

Create a new order with negative quantity and negative amount.total for each line item. Include the original orderId as purchaseOrderId:

POST /merchants/:merchantId/orders
{
  "terminal$id": "YOUR_TERMINAL_ID",
  "referenceId": "refund-order-001",
  "orderLines": [
    {
      "id": "ITEM-001",
      "purchaseOrderId": "ORIGINAL_ORDER_ID",
      "name": "Nike Shoes",
      "quantity": -2,
      "amount": {
        "regular": 10000,
        "total": -20000,
        "currency": "752",
        "tax": [
          { "amount": 4000, "percentage": 25, "type": "VAT" }
        ]
      }
    },
    {
      "id": "ITEM-002",
      "purchaseOrderId": "ORIGINAL_ORDER_ID",
      "name": "Apple Pods",
      "quantity": -1,
      "amount": {
        "regular": 20000,
        "total": -20000,
        "currency": "752",
        "tax": [
          { "amount": 4000, "percentage": 25, "type": "VAT" }
        ]
      }
    }
  ],
  "totalOrderAmount": {
    "regular": 30000,
    "total": -30000,
    "currency": "752",
    "tax": [
      { "amount": 8000, "percentage": 25, "type": "VAT" }
    ]
  },
  "controlFunctions": {
    "initiatePaymentsOptions": {
      "paymentMethod": "CARD_NP",
      "refundProcessingParams": {
        "purchasePaymentId": "ORIGINAL_PAYMENT_ID",
        "refundReason": "CUSTOMER_INITIATED_RETURN"
      }
    }
  }
}
// Response
{
  "status": "SUCCESS",
  "data": {
    "orderId": "83b2ca45889a317b0b",
    "paymentId": "83b2ca4564bd500606"
  },
  "message": "Order created successfully"
}

The terminal$id only needs to be a valid terminal — it does not have to be the same terminal that processed the original purchase.

Key details:

  • Set quantity to a negative value to indicate a return
  • Set amount.total to a negative value
  • Include the original purchaseOrderId on each line item
  • totalOrderAmount.total must be negative (the refund amount)

Payment Method for Refunds

Set paymentMethod to either the method the customer originally paid with, or CARD_NP:

Original Payment MethodRefund Method
CARDCARD_NP (recommended) or CARD
KLARNAKLARNA
SWISHSWISH
Other digital methodsSame as original

For card refunds, the two card methods behave differently:

MethodBehaviour
CARD_NPCard not present. Refunds straight back to the card that paid — no terminal interaction. This is the recommended default for card refunds.
CARDCard present. Triggers a card tap on the terminal, so a card must be physically presented to receive the refund.

Note: Transaction fees are charged again on refunds.

Refund Processing Parameters

Pass refund metadata through refundProcessingParams inside initiatePaymentsOptions:

{
  "controlFunctions": {
    "initiatePaymentsOptions": {
      "paymentMethod": "CARD_NP",
      "refundProcessingParams": {
        "purchasePaymentId": "ORIGINAL_PAYMENT_ID",
        "refundReason": "CUSTOMER_INITIATED_RETURN"
      }
    }
  }
}
ParameterRequiredDescription
purchasePaymentIdNoThe paymentId of the original purchase (returned when the original order was created). This is the payment-level reference, distinct from the purchaseOrderId you set on each line item.
refundReasonNoWhy the refund is being issued. See the allowed values below.
otherReasonConditionalFree-text explanation. Required when refundReason is OTHER.

Refund Reasons

ValueMeaning
CUSTOMER_INITIATED_RETURNThe customer returned the goods or requested the refund.
SUSPECTED_MALFUNCTIONThe product is suspected to be faulty or not working.
SUSPECTED_FRAUDThe transaction is suspected to be fraudulent.
DUPLICATE_TRANSACTIONThe original charge was a duplicate.
OTHERAny other reason — requires a message in otherReason.

When using OTHER, include the explanation:

{
  "controlFunctions": {
    "initiatePaymentsOptions": {
      "paymentMethod": "CARD_NP",
      "refundProcessingParams": {
        "purchasePaymentId": "ORIGINAL_PAYMENT_ID",
        "refundReason": "OTHER",
        "otherReason": "Goodwill credit for delayed delivery"
      }
    }
  }
}

Step 2: Check Refund Status

Verify the refund completed:

GET /merchants/:merchantId/orders/:orderId/status

The order status will show PAYMENT_COMPLETED once the refund is processed. You can also track refund status via webhooks.

Adjustments in Refunds

If the original order included adjustments (tips, discounts), the refund includes them by default. Control this with includeAdjustmentsForRefund:

{
  "controlFunctions": {
    "includeAdjustmentsForRefund": false,
    "initiatePaymentsOptions": {
      "paymentMethod": "CARD"
    }
  }
}

For partial returns, by default the first refund order includes adjustments (true) and subsequent ones do not (false).

Refund via Partner Portal

You can also process refunds through the UI:

  1. Log in to Partner Portal > Merchants > select merchant > Transactions
  2. Select the transaction to refund
  3. Click Create Refund > Full Refund > Process Refund

Refund FAQ

How long after a purchase can I issue a refund? Refunds can be issued up to 90 days after the original purchase. This limit is enforced by Surfboard across all payment methods — there is no difference between card, Swish, Klarna, or other methods. If you need to reverse a transaction older than 90 days (e.g., an event ticket refund a year later), it cannot be processed through the API.

How long does it take for the customer to receive the refund? Processing time depends on the payment method:

Payment MethodRefund Timeline
Card (CARD, CARD_NP)Up to 7 days. Depends on the issuer and acquirer fraud systems.
Swish (SSWISH, NSWISH)Instant
Vipps (SVIPPS)Instant
MobilePay (SMOBILEPAY)Up to 10 banking days
Klarna (KLARNA)Up to 10 days

Reference

Ready to get started?

Create a sandbox account and start building your integration today.