# Issue a refund (/platforms/checkout/issue-refund)



Refund a captured payment from a seller back to a buyer.

## Know before you code [#know-before-you-code]

> **Info:** To use this integration you must:
>
> * Be an [approved partner](/platforms/get-started).
> * [Onboard sellers](/platforms/seller-onboarding/) before you begin this integration.
> * Have an [access token](/platforms/create-account/#link-exchangeyourapicredentialsforanaccesstoken).
> * Inform your sellers of [PayPal's Seller Protection policy](https://www.paypal.com/us/webapps/mpp/security/seller-protection), so they are aware of use cases that invalidate that protection, such as shipping to an address other than the one in the transaction confirmation

## Generate PayPal Auth Assertion header [#generate-paypal-auth-assertion-header]

Pass the [PayPal-Auth-Assertion](/api/rest/requests/#paypal-auth-assertion) and the [PayPal-Partner-Attribution-Id](/api/rest/requests/#paypal-partner-attribution-id) headers with the standard `Content-Type`, `Authorization`, and `PayPal-Request-ID` headers. On the client side, you can generate the value of the `PayPal-Auth-Assertion` header as follows:

#### JavaScript

```text lineNumbers
function encodeObjectToBase64(object) {
    const objectString = JSON.stringify(object);
    return window.btoa(objectString);
}

const clientId = "CLIENT-ID";
const sellerPayerId = "SELLER-PAYER-ID"; // preferred
// const sellerEmail = "SELLER-ACCOUNT-EMAIL"; // use instead of payer-id if required

const header = {
    alg: "none"
};
const encodedHeader = encodeObjectToBase64(header);

const payload = {
    iss: clientId,
    payer_id: sellerPayerId
    // email: sellerEmail
};
const encodedPayload = encodeObjectToBase64(payload);

const jwt = `${encodedHeader}.${encodedPayload}.`; // json web token
console.log(`Paypal-Auth-Assertion=${jwt}`);
```

#### Node.js

```text lineNumbers
function encodeObjectToBase64(object) {
    const objectString = JSON.stringify(object);
    return Buffer
        .from(objectString)
        .toString("base64");
}

const clientId = "CLIENT-ID";
const sellerPayerId = "SELLER-PAYER-ID"; // preferred
// const sellerEmail = "SELLER-ACCOUNT-EMAIL"; // use instead if payer-id unknown

const header = {
    alg: "none"
};
const encodedHeader = encodeObjectToBase64(header);

const payload = {
    iss: clientId,
    payer_id: sellerPayerId
    // email: sellerEmail
};
const encodedPayload = encodeObjectToBase64(payload);

const jwt = `${encodedHeader}.${encodedPayload}.`; // json web token
console.log(`Paypal-Auth-Assertion=${jwt}`);
```

#### Java

```text lineNumbers
import org.apache.commons.codec.binary.Base64;

public class Base64Encode {

    public static void main(String[] args) {
        String clientId = "CLIENT-ID";
        String sellerPayerId = "SELLER-PAYER-ID"; // preferred
        // String sellerEmail = "SELLER-ACCOUNT-EMAIL"; // use instead if payer-id unknown

        String header = "{\"alg\":\"none\"}";
        String payload =
            "{\"iss\":\"" + clientId + "\",\"payer_id\":\"" + sellerPayerId + "\"}";
        // "{"iss":"" + clientId + "","email":"" + sellerEmail + ""}";

        byte[] encodedHeader = Base64.encodeBase64(header.getBytes());
        byte[] encodedPayload = Base64.encodeBase64(payload.getBytes());

        String jwt = new String(encodedHeader) +
            "." +
            new String(encodedPayload) +
            "."; // json web token
        System.out.println("Paypal-Auth-Assertion=" + jwt);
    }
}
```

> **Note:** **Note**: The token contains two period (.) characters, which are required according to the JSON web token structure.

### Modify the code [#modify-the-code]

Copy the code and modify the following:

* Use the client ID of the platform or marketplace from the PayPal Developer dashboard for `clientId`.
* In the given example, the `sellerPayerId` is the payer ID of the receiving seller's PayPal account. You can also use `email` instead of `payer_id` and supply the email address of the seller's PayPal account.

## Make refund request [#make-refund-request]

To refund an order, use the `/v2/payments/captures/{CAPTURE-ID}/refund` endpoint. The `CAPTURE-ID` can be read from the `purchase_units/payments/captures/id` field of the order you want to refund.

#### Full refund

```text lineNumbers
curl -v -X POST https://api-m.sandbox.paypal.com/v2/payments/captures/2GG279541U471931P/refund \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer ACCESS-TOKEN' \
  -H 'PayPal-Partner-Attribution-Id: BN-CODE' \
  -H 'PayPal-Auth-Assertion: AUTH-ASSERTION-JWT' \
  -H 'PayPal-Request-Id: REQUEST-ID' \
  -d '{}'
```

#### Partial refund

```text lineNumbers
curl -v -X POST https://api-m.sandbox.paypal.com/v2/payments/captures/2GG279541U471931P/refund \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer ACCESS-TOKEN' \
  -H 'PayPal-Partner-Attribution-Id: BN-CODE' \
  -H 'PayPal-Auth-Assertion: AUTH-ASSERTION-JWT' \
  -H 'PayPal-Request-Id: REQUEST-ID' \
  -d '{
    "amount": {
        "value": "10.99",
        "currency_code": "USD"
    }
}'
```

For a full refund, include an empty payload in the JSON request body.

For a partial refund, include the `amount` object in the JSON request body. You can also issue multiple partial refunds up to the total captured amount. If you are unsure how much captured amount is remaining to be refunded after one or more partial refunds, make the API call with the total captured amount or leave the amount field blank. The API will automatically calculate and issue the refund for the remaining value.

### Modify the code [#modify-the-code-1]

Copy the code and modify the following:

* Change `ACCESS-TOKEN` to your access token.
* Change `BN-CODE` to your [PayPal Attribution ID](/api/rest/requests/#paypal-partner-attribution-id) to receive revenue attribution. To find your BN code, see [Code and Credential Reference](/platforms/create-account/#link-bncode).
* Change `AUTH-ASSERTION-JWT` to your [PayPal-Auth-Assertion](/api/rest/requests/#paypal-auth-assertion) token.
* Change `REQUEST-ID` to a set of unique alphanumeric characters such as a timestamp to prevent duplicate transactions.

### Step result [#step-result]

A successful request returns the `HTTP 201 Created` status code. If you didn't receive a response, making the same API call without changing the request should result in an `HTTP 200 OK` with a confirmation of the refund.

## Next steps [#next-steps]

> **Info:** [Refund Resource](/api/payments/v2/captures-refund)
>
> For more information about the refunds API, see the Payment API.

> **Info:** [Integration Checklist](/platforms/integration-checklist)
>
> Go through the integration checklist before you go live.
