curl --request POST \
--url https://api.sandbox.primer.io/payments/{id}/refund \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"amount": 42,
"orderId": "order-1234-refund",
"reason": "Customer returned order #1234."
}
'import requests
url = "https://api.sandbox.primer.io/payments/{id}/refund"
payload = {
"amount": 42,
"orderId": "order-1234-refund",
"reason": "Customer returned order #1234."
}
headers = {
"X-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
amount: 42,
orderId: 'order-1234-refund',
reason: 'Customer returned order #1234.'
})
};
fetch('https://api.sandbox.primer.io/payments/{id}/refund', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.primer.io/payments/{id}/refund",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 42,
'orderId' => 'order-1234-refund',
'reason' => 'Customer returned order #1234.'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sandbox.primer.io/payments/{id}/refund"
payload := strings.NewReader("{\n \"amount\": 42,\n \"orderId\": \"order-1234-refund\",\n \"reason\": \"Customer returned order #1234.\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sandbox.primer.io/payments/{id}/refund")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 42,\n \"orderId\": \"order-1234-refund\",\n \"reason\": \"Customer returned order #1234.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sandbox.primer.io/payments/{id}/refund")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 42,\n \"orderId\": \"order-1234-refund\",\n \"reason\": \"Customer returned order #1234.\"\n}"
response = http.request(request)
puts response.read_body{
"id": "kHdEw9EG",
"date": "2021-02-21T15:36:16.367687",
"status": "SETTLED",
"orderId": "order-abc",
"customerId": "customer-123",
"currencyCode": "EUR",
"amount": 42,
"paymentMethod": {
"paymentMethodToken": "heNwnqaeRiqvY1UcslfQc3wxNjEzOTIxNjc4",
"isVaulted": true,
"descriptor": "Purchase: Socks",
"analyticsId": "VtkMDAxZW5isH0HsbbNxZ3lo",
"paymentMethodType": "PAYMENT_CARD",
"paymentMethodData": {
"first6Digits": "411111",
"firstDigits": "41111111",
"last4Digits": "1111",
"expirationMonth": "12",
"expirationYear": "2030",
"cardholderName": "John Biggins",
"network": "Visa",
"isNetworkTokenized": false,
"binData": {
"network": "VISA",
"regionalRestriction": "UNKNOWN",
"accountNumberType": "UNKNOWN",
"accountFundingType": "UNKNOWN",
"prepaidReloadableIndicator": "NOT_APPLICABLE",
"productUsageType": "UNKNOWN",
"productCode": "VISA",
"productName": "VISA"
}
}
},
"processor": {
"name": "STRIPE",
"processor_merchant_id": "acct_stripe_1234",
"amountCaptured": 42,
"amountRefunded": 42
},
"transactions": [
{
"type": "SALE",
"processorStatus": "SETTLED",
"processorName": "STRIPE",
"processorMerchantId": "acct_stripe_1234",
"processorTransactionId": "54c4eb5b3ef8a"
},
{
"type": "REFUND",
"processorStatus": "SETTLED",
"processorName": "STRIPE",
"processorMerchantId": "acct_stripe_1234",
"processorTransactionId": "54c4eb5b3ef8a",
"reason": "Customer returned order #1234."
}
],
"customer": {
"email": "customer123@gmail.com"
},
"metadata": {
"productId": 123,
"merchantId": "a13bsd62s"
}
}Refund a payment
By default, this request will refund the full amount.
Optionally, pass in a lesser amount for a partial refund.
Failed request limit: Primer limits how many failed requests a single
payment can have. Failed capture, cancel and refund requests all count towards
the same limit, which is currently 100 per payment. Once a payment reaches the
limit, any further capture, cancel or refund request for that payment is
rejected with a 409 and the error ID PaymentRequestLimitExceeded. The
rejected request is not sent to the processor. Do not retry after this error:
retrieve the payment to see why its previous requests failed, and contact Primer
support if you need the payment unblocked.
curl --request POST \
--url https://api.sandbox.primer.io/payments/{id}/refund \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"amount": 42,
"orderId": "order-1234-refund",
"reason": "Customer returned order #1234."
}
'import requests
url = "https://api.sandbox.primer.io/payments/{id}/refund"
payload = {
"amount": 42,
"orderId": "order-1234-refund",
"reason": "Customer returned order #1234."
}
headers = {
"X-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
amount: 42,
orderId: 'order-1234-refund',
reason: 'Customer returned order #1234.'
})
};
fetch('https://api.sandbox.primer.io/payments/{id}/refund', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.primer.io/payments/{id}/refund",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 42,
'orderId' => 'order-1234-refund',
'reason' => 'Customer returned order #1234.'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sandbox.primer.io/payments/{id}/refund"
payload := strings.NewReader("{\n \"amount\": 42,\n \"orderId\": \"order-1234-refund\",\n \"reason\": \"Customer returned order #1234.\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sandbox.primer.io/payments/{id}/refund")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 42,\n \"orderId\": \"order-1234-refund\",\n \"reason\": \"Customer returned order #1234.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sandbox.primer.io/payments/{id}/refund")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 42,\n \"orderId\": \"order-1234-refund\",\n \"reason\": \"Customer returned order #1234.\"\n}"
response = http.request(request)
puts response.read_body{
"id": "kHdEw9EG",
"date": "2021-02-21T15:36:16.367687",
"status": "SETTLED",
"orderId": "order-abc",
"customerId": "customer-123",
"currencyCode": "EUR",
"amount": 42,
"paymentMethod": {
"paymentMethodToken": "heNwnqaeRiqvY1UcslfQc3wxNjEzOTIxNjc4",
"isVaulted": true,
"descriptor": "Purchase: Socks",
"analyticsId": "VtkMDAxZW5isH0HsbbNxZ3lo",
"paymentMethodType": "PAYMENT_CARD",
"paymentMethodData": {
"first6Digits": "411111",
"firstDigits": "41111111",
"last4Digits": "1111",
"expirationMonth": "12",
"expirationYear": "2030",
"cardholderName": "John Biggins",
"network": "Visa",
"isNetworkTokenized": false,
"binData": {
"network": "VISA",
"regionalRestriction": "UNKNOWN",
"accountNumberType": "UNKNOWN",
"accountFundingType": "UNKNOWN",
"prepaidReloadableIndicator": "NOT_APPLICABLE",
"productUsageType": "UNKNOWN",
"productCode": "VISA",
"productName": "VISA"
}
}
},
"processor": {
"name": "STRIPE",
"processor_merchant_id": "acct_stripe_1234",
"amountCaptured": 42,
"amountRefunded": 42
},
"transactions": [
{
"type": "SALE",
"processorStatus": "SETTLED",
"processorName": "STRIPE",
"processorMerchantId": "acct_stripe_1234",
"processorTransactionId": "54c4eb5b3ef8a"
},
{
"type": "REFUND",
"processorStatus": "SETTLED",
"processorName": "STRIPE",
"processorMerchantId": "acct_stripe_1234",
"processorTransactionId": "54c4eb5b3ef8a",
"reason": "Customer returned order #1234."
}
],
"customer": {
"email": "customer123@gmail.com"
},
"metadata": {
"productId": 123,
"merchantId": "a13bsd62s"
}
}Authorizations
Headers
Optional key to make the request idempotent. Enables a safe retry of a request without risking the user being charged or refunded multiple times. The idempotency key must be generated by the client and needs to be unique for every new request.
Path Parameters
ID of payment to refund.
8 - 9^[a-zA-Z0-9]{8,9}$Body
The amount you would like to refund the customer, in minor units. e.g. for $7, use 700.
Defaults to remaining non-refunded amount.
x >= 0Optionally you can pass a specific order ID for the refund.
By default this will be set to the original orderId given on payment creation.
You can optionally specify a reason for the refund. This is for your own records.
Response
Successful Response
The unique payment ID.
You can use this ID to retrieve the payment details, or perform downstream operations.
The date and time at which the payment was created in UTC format.
See the payment status table for more information.
PENDING, FAILED, AUTHORIZED, SETTLING, PARTIALLY_SETTLED, SETTLED, DECLINED, CANCELLED Your reference for the payment.
The 3-letter currency code in ISO 4217 format. e.g. use USD for US dollars.
The amount you charged the customer, in minor units.
x >= 0More information associated with the order.
Show child attributes
Show child attributes
The unique identifier for your customer.
More information associated with the customer.
Show child attributes
Show child attributes
Additional data to be used throughout the payment lifecycle.
The payment method options provided in the request, as well as the token used to process the payment.
Show child attributes
Show child attributes
More information associated with the payment processor, including the processor name.
Show child attributes
Show child attributes
Required action to perform in order to resume the payment workflow. This can be requiring a 3DS check from the customer for instance.
Show child attributes
Show child attributes
Check this field for more information regarding the payment's status. This is especially useful when the status is DECLINED or FAILED.
Show child attributes
Show child attributes
A list summarizing the transactions that occurred while processing the payment.
Note: a refund is a separate transaction and so will appear in this transactions list if a refund was performed.
Show child attributes
Show child attributes