# PayPal

## Introduction

The integration with PayPal supports both in-checkout and post-checkout payment approaches. To learn about the details, see the [PayPal Commerce Platform Gateway Guide](https://docs.spreedly.com/payment-gateways/paypal-commerce-platform/) documentation.

### In-checkout flow

Payment done during the checkout requires an `https://api.emporix.io/checkout/{TENANT}/checkouts/orders` `POST` request, with the `paymentMethods` field including the following information:

```json
paymentMethods : [
  {
    "provider": "payment-gateway",
    "method": "paypal",
    "customAttributes": {
      "token": "Akon8nPXtz0oahVYEqPsoI7pz4l",
      "modeId": "92d77b2b-9385-43ad-a859-55176fbcbd2f",
      "customer": "61443563"
    }
  }
] 
```

* `provider` - Should always be set to payment-gateway.
* `method` - Reflects one of the payment mode codes, depending on the method that you want to choose. You can see the list of available modes after sending the `GET` request: `https://api.emporix.io/payment-gateway/{TENANT}/paymentmodes/frontend`.
* `customAttributes` - It's a set of attributes specific for the particular payment mode.
  * `token` - Credit card token for a tokenized approach.
  * `modeId` - Payment mode identifier, the ID should reflect the payment mode ID that you receive from `GET`: `https://api.emporix.io/payment-gateway/{TENANT}/paymentmodes/frontend`.
  * `customer` - Identifier of a customer that does the checkout and payment.

With this flow, the payment authorization is done during the checkout process. The response to the checkout request contains the `paymentDetails` object:

```json
{
    "orderId": "EON1772",
    "paymentDetails": {
        "externalPaymentHttpMethod": "GET",
        "authorizationToken": "AVTqLLj26KFCVQtfOXrAkymfpR9",
        "externalPaymentRedirectURL": "https://www.paypal.com/checkoutnow?token=2KY55219L2352861G"
    },
    "checkoutId": null
}
```

The `externalPaymentRedirectURL` field is populated only in case when a redirect is required. The URL is used to navigate the user in order to finish the payment process.

When the user finishes the whole flow on the PayPal side, the Emporix payment gateway is notified about the result of the operation by a callback. It may take around one minute as this is an asynchronous operation.

The diagram shows how PayPal sequence looks like when it's integrated with Emporix for the in-checkout flow:

<figure><img src="/files/oInpFpvxuO2qMiX0Z7QG" alt=""><figcaption></figcaption></figure>

### Post-checkout flow

The post-checkout approach assumes that a customer does a checkout without pointing to any payment methods. This stage happens after the checkout, when an actual order is already created.

Payment done after the checkout requires an `https://api.emporix.io/checkout/{TENANT}/checkouts/orders` `POST` request, with the `paymentMethods` field including the following information:

```json
paymentMethods : [
  {
    "provider": "payment-gateway",
    "customAttributes": {
      "customer": "61443563",
      "deferred": true
    }
  }
]
```

* `provider` - Should always be set to payment-gateway.
* `customAttributes` - It's a set of attributes specific for the particular payment mode.
  * `customer` - Identifier of the customer that does the checkout and payment.
  * `deferred` - Should be set to `true`.

For this flow the payment authorization is **NOT** done automatically during the checkout process. Therefore, as a response of the checkout request you can receive the following response with missing `paymentDetails` fields:

```json
{
  "orderId":"EON1775",
  "paymentDetails":null,
  "checkoutId":null
}
```

When an order is placed, the storefront should display all the available payment options and allow the user to choose the relevant one, in this case PayPal.\
Having the payment option chosen and all payment details provided, storefront should invoke the following payment-gateway endpoint: `https://api.emporix.io/payment-gateway/{TENANT}/payment/frontend/authorize`\
`POST`:

```json
{
  "order": {
      "id":"EON1775"
  },
  "paymentModeId":"ef48f439-1c3c-42ff-807d-ef4cac237745",
  "creditCardToken":"9QpMHzNNZDCHVF47hL9ZDP18RFr"
}
```

* `Order id` - A mandatory field, it needs to be an order created by a customer that invokes the authorization endpoint. Otherwise, a validation error is returned.
* `paymentModeId` - payment mode identifier - Reflect the payment mode ID that you received from `GET`: `https://api.emporix.io/payment-gateway/{TENANT}/paymentmodes/frontend`.
* `creditCardToken` - The field should contain the token received by the Spreedly library.

**Response**:

```json
{
    "successful": true,
    "paymentTransactionId": "afddff82-de4e-45b8-8de5-3f722b81116b",
    "authorizationToken": "2IKNTd5K2HlYqjmGt8n7JgICWuG",
    "requiresExternalPayment": true,
    "externalPaymentRedirectURL": "https://www.paypal.com/checkoutnow?token=49C50265AF458692S",
    "externalPaymentHttpMethod": "GET"
}
```

Pay attention to the `paymentDetails.externalPaymentRedirectURL` value. To finish the payment, you should redirect the user to the relevant URL, payment flow on the PayPal website.

When the user finishes the whole flow on the PayPal side, the Emporix payment gateway is notified about the result of the operation by a callback. It may take around one minute as this is an asynchronous operation.

The diagram shows how PayPal sequence looks like when it's integrated with Emporix for the post-checkout flow:

<figure><img src="/files/ZufQdPIQqxJY3pwrC8we" alt=""><figcaption></figcaption></figure>

### Gateway configuration

1. To start with the gateway configuration, execute the following request:

```js
curl https://core.spreedly.com/v1/gateways.xml \
--header 'Authorization: Basic {SPREEDLY_TOKEN}' \
-H 'Content-Type: application/xml' \
-d '<gateway>
  <gateway_type>paypal_commerce_platform</gateway_type>
  <login>client id</login>
  <password>secret</password>
</gateway>'
```

* `SPREEDLY_TOKEN` - Is a result of the base64 of `environment_key:access_secret`.
* `client_id` and `secret` can be fetched directly from your PayPal account. For more information, see [PayPal Gateway Credentials](https://docs.spreedly.com/payment-gateways/paypal-commerce-platform/#gateway-credentials) documentation.

**Result**:

```js
<gateway>
    <token>5S0kV27BrZ0Z47TdGK4v1OI7ojB</token>
    ...
</gateway>  
```

{% hint style="danger" %}
Store the token value for the next steps in the configuration.\
If you lose the token value at any point, use the following request to get it:

```js
curl --location --request GET 'https://core.spreedly.com/v1/gateways.json' \
--header 'Authorization: Basic {SPREEDLY_TOKEN}'
```

{% endhint %}

2. To configure the Emporix Payment Gateway service, execute the following request:

```js
curl --location --request POST 'https://api.emporix.io/payment-gateway/{TENANT}/paymentmodes/config' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer {EMPORIX_AUTH_TOKEN}' \
--data-raw '{
    "code": "paypal",
    "active": true,
    "provider": "SPREEDLY",
    "configuration": {
        "Spreedly/GatewayToken": "{SPREEDLY_GATEWAY_KEY}",
        "Spreedly/EnvironmentKey": "{SPREEDLY_ENVIRONMENT_KEY}",
        "Spreedly/AccessSecret": "{SPREEDLY_ACCESS_SECRET}",
        "Spreedly/PaymentMethodType": "paypal",
        "Spreedly/RedirectURL": "{REDIRECT_URL}",
        "Spreedly/SignatureSecret": "{SPREEDLY_SIGNATURE_SECRET}"
    }
}'
```

* EMPORIX\_AUTH\_TOKEN - The standard access token. To check how to get the token see [OAuth Service](/api-references/api-guides/authentication/oauth-service.md) documentation.
* SPREEDLY\_GATEWAY\_KEY - Spreedly gateway token that was returned when you configured the payment gateway on the Spreedly side.
* SPREEDLY\_ENVIRONMENT\_KEY - Spreedly environment key that you got from the Emporix support team.
* SPREEDLY\_ACCESS\_SECRET - Spreedly secret key that you got from the Emporix support team.
* REDIRECT\_URL - The URL to your storefront where the user is redirected when the payment is done.
* SPREEDLY\_SIGNATURE\_SECRET - Spreedly signature secret that you got from the Emporix support team.

## Storefront implementation

To use Paypal payment, you have to generate a token in Spreedly.\
You can do this in two ways:

* Display a button that does the form submission - as described in [PayPal Commerce Platform Offsite Payments](https://docs.spreedly.com/guides/offsite-payments/ppcp/).
* Execute the following (an example in react):

```js
const generateToken = () => {
    var formData = new FormData();
    formData.append("redirect_url", window.location.href)
    formData.append("environment_key", {SPREEDLY_ENVIRONMENT_KEY})
    formData.append("payment_method_type", "paypal")
    
    axios({
      method: "post",
      url: "https://core.spreedly.com/v1/payment_methods.json",
      data: formData,
      headers: { "Content-Type": "multipart/form-data" },
    })
      .then(function (response) {
        storeToken(response)
      })
      .catch(function (response) {
        storeToken(response)
      });
  }
  
  const storeToken = (response) => {
    const url = new URL(response.request.responseURL)
    const token = url.searchParams.get("token")
    window.console.log("TOKEN", token)
    setPayment({
      provider: 'payment-gateway',
      mode: "offsite",
      method: 'paypal',
      displayName: 'Paypal',  
      customAttributes:  {
        token : token,
        modeId : paymentMode.id,
        customer : props.customerId
      }
    })
  }
```

The payment information is stored because it's needed during the checkout call. The payment object during the checkout request should look like:

```json
{
...
"paymentMethods": [
  {
      "provider": "payment-gateway",
      "method": "paypal",
      "customAttributes": {
          "token": "8Ny2OGn1dwzPBuBdwSej95qAuHN",
          "modeId": "227fed5b-e91a-473e-88ea-3b0e85db8408",
          "customer": "17071158"
      }
  }
]
...
}
```

**Result**:

```json
{
    "orderId": "EON1011",
    "paymentDetails": {
        "externalPaymentHttpMethod": "GET",
        "authorizationToken": "nzQPTC2skR6Fb3LgOagBmVGCBC",
        "externalPaymentRedirectURL": "https://www.paypal.com/checkoutnow?token=2KY55219L2352861G"
    },
    "checkoutId": null
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developer.emporix.io/ce/extensibility-and-integrations/payments/paypal.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
