Skip to main content
POST /v2/payments/retailPay Initiates a retail payment where the merchant scans the customer’s wallet QR code or barcode. This is the “Customer Presented Mode” (CPM) flow for in-store payments.

Use Case

The customer opens their Rebell wallet app and displays their payment QR code or barcode. The merchant scans this code and initiates the payment.
1

Customer Displays Code

Customer opens Rebell app and shows their payment QR/barcode
2

Merchant Scans

Merchant POS scans the code to get the paymentAuthCode
3

API Call

Merchant backend calls retailPay with the scanned code
4

Payment Processed

Payment is processed immediately (synchronous response)
5

Webhook Notification

Merchant receives webhook confirmation

Request Parameters

productCode
string
required
Payment product code assigned by Rebell.Max length: 32 characters
paymentRequestId
string
required
Merchant-generated unique identifier (idempotency key). Must be unique per transaction.Max length: 64 characters
paymentAuthCode
string
required
The QR code or barcode content scanned from the customer’s wallet.Max length: 128 characters
paymentAmount
object
required
Payment amount details.
order
object
Order details.
paymentNotifyUrl
string
required
Webhook URL to receive payment notifications.Max length: 2048 characters
extendInfo
string
Extended information as JSON string.Max length: 2048 characters

Response Parameters

result
object
required
Standard result object with resultCode, resultStatus, resultMessage
paymentRequestId
string
Echo of the merchant’s payment request ID
paymentId
string
Rebell-assigned payment identifier for tracking and reconciliation
paymentTime
string
Payment completion time in ISO 8601 format
paymentAmount
object
Confirmed payment amount

Example Request

{
  "productCode": "5105010010000100040",
  "paymentRequestId": "RETAIL-20240110-001",
  "paymentAuthCode": "289123456789012345",
  "paymentAmount": {
    "currency": "EUR",
    "value": "2500"
  },
  "order": {
    "orderDescription": "Coffee and pastry",
    "merchant": {
      "store": {
        "externalStoreId": "STORE_001"
      }
    }
  },
  "paymentNotifyUrl": "https://merchant.example.com/webhooks/payment"
}

Example Response

Success:
{
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "success"
  },
  "paymentRequestId": "RETAIL-20240110-001",
  "paymentId": "2024011012345678901234",
  "paymentTime": "2024-01-10T14:30:45+01:00",
  "paymentAmount": {
    "currency": "EUR",
    "value": "2500"
  }
}
Processing (async):
{
  "result": {
    "resultCode": "PAYMENT_IN_PROCESS",
    "resultStatus": "U",
    "resultMessage": "Payment is being processed"
  },
  "paymentRequestId": "RETAIL-20240110-001",
  "paymentId": "2024011012345678901234"
}

Result Codes

resultStatusresultCodeDescriptionAction
SSUCCESSPayment successfulComplete the transaction
FORDER_IS_CLOSEDOrder already completedCheck order status
FINVALID_AUTH_CODEAuth code invalid or expiredAsk customer to refresh code
FINSUFFICIENT_BALANCECustomer has insufficient fundsInform customer
FRISK_REJECTPayment rejected by risk systemTry alternative payment
UPAYMENT_IN_PROCESSPayment processingPoll with inquiryPayment
UUNKNOWN_EXCEPTIONUnknown errorRetry or poll status

Implementation Example

async function processRetailPayment(authCode, amount, orderId) {
  const paymentRequestId = `RETAIL-${orderId}-${Date.now()}`;

  const response = await rebellAPI.retailPay({
    productCode: process.env.REBELL_PRODUCT_CODE,
    paymentRequestId,
    paymentAuthCode: authCode,
    paymentAmount: {
      currency: 'EUR',
      value: String(amount)
    },
    order: {
      orderDescription: `Order #${orderId}`,
      merchant: {
        store: { externalStoreId: process.env.STORE_ID }
      }
    },
    paymentNotifyUrl: `${process.env.BASE_URL}/webhooks/payment`
  });

  if (response.result.resultStatus === 'S') {
    // Payment successful
    return {
      success: true,
      paymentId: response.paymentId,
      paymentTime: response.paymentTime
    };
  }

  if (response.result.resultStatus === 'U') {
    // Payment processing - need to poll
    return {
      success: false,
      pending: true,
      paymentId: response.paymentId,
      paymentRequestId
    };
  }

  // Payment failed
  throw new PaymentError(response.result.resultCode, response.result.resultMessage);
}

Inquiry Payment

Check payment status when result is unknown

Payment Notify

Handle payment webhooks