PayPal

PayPal
PayPal is a platform that acts as an intermediary in online payment transactions, allowing users to make and receive payments securely and quickly.
In essence, PayPal simplifies the digital payment process by providing a secure, global, and convenient experience for buyers and sellers.
Supported operations
| Operation | Description |
|---|---|
| ✅ Payment authorization | Blocks funds on the customer's card. |
| ✅ Payment capture | Completes the transaction and transfers the funds. |
| ✅ Direct payment | Combines authorization and capture in one step. |
| ✅ Refund | Returns the full amount of a transaction. |
| ✅ Partial refund | Returns part of the captured amount. |
| ✅ Authorization cancellation | Reverses an authorization that was not captured. |
Integration
1. Configure PayPal as a payment method
To integrate PayPal, you must first perform a series of configurations from the OrkestaPay portal. Visit our Providers configuration guide and find the PayPal payment method.
2. Implement payment button
To tokenize the payment data, follow these steps:
- Include OrkestaPay scripts: Use the OrkestaPay scripts in your web application.
- Initialize parameters: Define the OrkestaPay credentials here, as well as data related to the payment to be processed.
- Render the payment button: Place the PayPal button in your frontend.
Required resources:
CSS
<link
rel="stylesheet"
href="https://checkout.orkestapay.com/web/components/payment-methods/styles.css"
integrity="sha384-5/NLomvLQk75JVAmEdaNkdkgLavuAlRS256szA++bmuw6Zph/wFYlWFHz9Fss7JF"
crossorigin="anonymous"
/>JS
<script
src="https://checkout.orkestapay.com/script/orkestapay.js"
integrity="sha384-lQoLMYDY2Cz/Y+8BLiNbhfLVHWawqsA/gE/8WRTpF6ZS3EABNKXhrq/0bBu4M1aI"
crossorigin="anonymous"
></script>
<script
src="https://checkout.orkestapay.com/web/components/payment-methods/main.js"
integrity="sha384-hvoIO7IyazX+Cc2LqBdHXx7Z3tq766248YzywLTN+D6f41Lub/VHUh2Pe5Q7WKfA"
crossorigin="anonymous"
></script>Code example
In the following code snippet there are certain parameters that need to be replaced with your merchant data:
public_key: Public key; these credentials can be obtained from the OrkestaPay portal.merchant_id:Merchant ID; these credentials can be obtained from the OrkestaPay portal.is_sandbox:Defines whether the credentials you are about to use are for testing or production.
In this example, sensitive credentials are captured in a form. These credentials must be handled from the backend.
client_id: This key, together with the secret key, will allow authentication to communicate with the OrkestaPay API. It is used on the server.client_secret:This key, together with the access key, will allow authentication to communicate with the OrkestaPay API. It is used on the server.
INFORMATIONTo consult OrkestaPay credentials, you can visit our guide Get API keys.
<!DOCTYPE html>
<html lang="en">
<head>
<base href="/" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="apple-touch-icon" type="image/x-icon" href="favicon.ico" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<title>PayPal web component</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous"
/>
<link rel="stylesheet" href="https://checkout.orkestapay.com/web/components/payment-methods/styles.css" />
<style>
.code {
color: inherit;
overflow-wrap: break-word;
white-space: pre-wrap;
}
</style>
</head>
<body>
<main class="container">
<section class="row mt-5">
<h1 id="card-title" class="col-12 text-center">OrkestaPay payment method PayPal web component</h1>
</section>
<section class="row">
<article class="col-12 col-md-6 offset-md-3">
<div class="row">
<section class="pt-3 col-12 col-md-6">
<label for="client-id" class="form-label"> OrkestaPay client ID <span class="text-danger">*</span> </label>
<input type="text" id="client-id" class="form-control" />
<small id="client-id-error" class="text-danger"> </small>
</section>
<section class="pt-3 col-12 col-md-6">
<label for="client-secret" class="form-label"> OrkestaPay client secret <span class="text-danger">*</span> </label>
<input type="password" id="client-secret" class="form-control" />
<small id="client-secret-error" class="text-danger"> </small>
</section>
</div>
</article>
<article id="button-container" class="col-12 col-md-6 offset-md-3"></article>
<article class="pt-3 col-12">
<div id="payment-details" class="w-100 alert" role="alert"></div>
</article>
</section>
</main>
<noscript> Please enable JavaScript to continue using this application. </noscript>
<script type="text/javascript" src="https://checkout.orkestapay.com/script/orkestapay.js"></script>
<script type="text/javascript" src="https://checkout.orkestapay.com/web/components/payment-methods/main.js"></script>
<script type="text/javascript">
//#region FRONTEND
let orkestaPay;
let paymentId = null;
const clientId = document.getElementById("client-id");
const clientSecret = document.getElementById("client-secret");
const { public_key, merchant_id, is_sandbox, country_code, currency, amount } = initValues();
(async function main() {
orkestaPay = initOrkestaPay({ is_sandbox, merchant_id, public_key });
const payPalButton = document.createElement("orkestapay-paypal-button");
await customElements.whenDefined("orkestapay-paypal-button");
payPalButton.params = {
payment_details: { currency, createPayment, confirmPayment },
theme: {
color: "gold",
height: 48,
shape: "rect",
},
};
const container = document.getElementById("button-container");
container.appendChild(payPalButton);
})();
function handlePaymentCreated(payment) {
const code = document.createElement("code");
code.innerHTML = JSON.stringify(payment, null, 2);
code.classList.add("code");
const paymentDetails = document.getElementById("payment-details");
paymentDetails.classList.add("alert-success");
paymentDetails.replaceChildren(code);
paymentId = payment.payment_id;
return paymentId ?? null;
}
function initValues() {
const url = new URL(window.location.href);
return {
public_key: "<REPLACE_WITH_YOUR_PUBLIC_KEY>",
merchant_id: "<REPLACE_WITH_YOUR_MERCHANT_ID>",
is_sandbox: true,
country_code: "MX",
currency: "MXN",
amount: "100.00",
};
}
//#endregion FRONTEND
//#region BACKEND
async function createPayment(paymentMethod) {
if (!paymentMethod) return null;
const { payment_method_id } = paymentMethod;
const order = await createOrder();
if (!order) return null;
const { order_id } = order;
const deviceInfo = await orkestaPay.getDeviceInfo();
if (!deviceInfo) return;
const { device_session_id } = deviceInfo;
const url = `${orkestaPay.getApiUrl()}/v1/payments`;
const Authorization = await authenticate();
const body = JSON.stringify({
payment_source: { type: "PAYPAL", payment_method_id },
device_session_id,
order_id,
});
return fetch(url, {
method: "POST",
headers: {
Authorization,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body,
})
.then(handleFetchResponse)
.then(handlePaymentCreated)
.catch(handleFetchError);
}
async function confirmPayment() {
if (!paymentId) return;
const url = `${orkestaPay.getApiUrl()}/v1/payments/${paymentId}/confirm`;
const Authorization = await authenticate();
const body = JSON.stringify({});
return fetch(url, {
method: "POST",
headers: {
Authorization,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body,
})
.then(handleFetchResponse)
.then(handlePaymentCreated)
.catch(handleFetchError);
}
async function createOrder() {
const url = `${orkestaPay.getApiUrl()}/v1/orders`;
const Authorization = await authenticate();
const body = JSON.stringify({
merchant_order_id: crypto.randomUUID(),
subtotal_amount: amount,
total_amount: amount,
country_code,
customer: {
email: "[email protected]",
},
currency,
products: [
{
product_id: crypto.randomUUID(),
quantity: 1,
unit_price: amount,
name: "A random product",
},
],
});
return fetch(url, {
method: "POST",
headers: { Authorization, "Content-Type": "application/json" },
body,
})
.then(handleFetchResponse)
.catch(handleFetchError);
}
async function authenticate() {
const url = `${orkestaPay.getApiUrl()}/v1/oauth/tokens`;
const body = JSON.stringify({
client_id: clientId.value.trim(),
client_secret: clientSecret.value.trim(),
grant_type: "client_credentials",
});
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body,
})
.then(handleFetchResponse)
.catch(handleFetchError);
if (!response) return null;
const { token_type, access_token } = response;
return `${token_type} ${access_token}`;
}
function handleFetchResponse(response) {
return response.ok ? response.json() : Promise.reject(body);
}
function handleFetchError(error) {
console.error(error);
return null;
}
//#endregion BACKEND
</script>
</body>
</html>
NOTEThis code is for demonstration purposes only, integrating frontend code and code that should be executed from a backend. Therefore, it is your responsibility to implement with best practices.
Code explanation
Initial Variables and Functions
orkestaPay: Main object to interact with the OrkestaPay API.paymentId: Stores the current payment ID.initValues(): Initial configuration, such as keys and transaction details (amount, currency, etc.).
main function
main function- Self-executing function that:
- Initializes OrkestaPay with initial values.
- Creates a PayPal button as a Web Component (
<orkestapay-paypal-button>). - Configures button parameters:
payment_details: Defines functions to create and confirm payments.theme: Visual customization (color, shape, height).
- Adds the button to the container (
button-container).
Backend operations
Authentication (authenticate)
authenticate)- Generates an access token:
- Sends the client credentials (
client_idandclient_secret) to the API. - Returns a token used to authorize requests.
- Sends the client credentials (
Order registration (createOrder)
createOrder)- Creates a new order:
- Includes basic information such as total amount, currency, and products (fictional in this case).
Payment creation (createPayment)
createPayment)- Receives a payment method (
paymentMethod). - Steps:
- Registers an order (
createOrder). - Obtains device information.
- Sends a
POSTrequest to the API to create a payment. - Handles the response and updates the payment details (
handlePaymentCreated).
- Registers an order (
Payment confirmation (confirmPayment)
confirmPayment)- Confirms the previously created payment via its
paymentId.
Response and error handling
handleFetchResponse(response): Returns the response body if successful; otherwise, rejects the promise.handleFetchError(error): Displays errors in the console.
Testing
To complete an integration test you must have a personal PayPal sandbox account.
NOTEFor more information about testing with PayPal, refer to their official documentation: https://developer.paypal.com/tools/sandbox/
