Receiving Payments from Oracle APEX with PayPal

Search for a command to run...

No comments yet. Be the first to comment.
Introduction One of the marquee features of APEX 26.1 was AI Interactive Reports. When I started testing this new feature, I was interested to see what was going on behind the scenes. In this post, I

Introduction One of the marquee features of APEX 26.1 is APEX AI Agents. APEX AI Agents allow you to use an LLM and your own PL/SQL and JS tools to perform actions on your data instead of just chattin

Introduction In my previous post, I looked at logging APEX AI Agent requests and responses with Request and Response handlers. Logging is the first step because it shows you what is actually moving th

Introduction Logging is one of the first things you need when building serious AI Agents. Without it, debugging quickly becomes guesswork. You can see the final answer, but not always why the model ch

Context management patterns from building agents in Oracle APEX

In this post, I will guide you through building an integration between Oracle APEX and PayPal. I will show you how to set up a developer account in PayPal and perform test transactions (in the PayPal Sandbox) from an Oracle APEX Application. This post is not intended to be a comprehensive guide to building a production-ready integration, but it will accelerate your journey.
PayPal is a global leader in online payment solutions, with over 325 million accounts worldwide. At the time of writing this post, PayPal is available in 202 countries and 25 currencies around the world. PayPal enables global eCommerce by making payments possible across different locations, currencies, and languages.
This section will cover the PayPal setups required for the integration. These setups include signing up for a Developer Account, creating test user accounts, and getting credentials to use in our APEX application.

PayPal provides a Sandboxed environment where you can perform end-to-end integration testing without generating any actual payments. As part of the Sandbox, PayPal supports two account types; personal and business (see screenshot below). These accounts behave precisely like real PayPal accounts; you can even log in as these users to view payments, etc.
PayPal creates default personal and business accounts during sign-up. As you can see, these are not very meaningful:

I think of a Personal Account as a Consumer Account and a Business Account as a Merchant Account.
For this post, we will create two more meaningful accounts:
Follow these steps to complete their setup:


We must create a new 'App' in the PayPal developer portal. Creating a new App will generate a unique set of credentials for this integration. I have named my App 'APEX Demo'.


❗At this point, you have provisioned a developer account and a Sandbox in which you can safely perform test transactions. Nothing you do here will generate any actual payments.
You will find the following links helpful in building your integration. I suggest reviewing this documentation before you start the integration with APEX.
I have built a Demo APEX Application to demonstrate the integration. You can download the demo app here.
You must perform all the PayPal setup steps above to use the demo App.
The App is a basic demonstration of a shopping cart where users can buy country flags. The App was built with APEX 22.1, and you can install and run it on apex.oracle.com. APEX Collections drive the application, so no dependent objects need to be installed. Please note that the demo app is by no means production-ready.
⏰ Change the Before Header process 'Prepare Checkout' on Page 2 to set P2_PAYPAL_CLIENT_ID to the PayPal App Client ID you created above.
The integration hinges on five fundamental activities:
The PayPal SDK can be loaded with your APEX page by referencing it in the page's JavaScript 'File URLs' section.

You can see that the URL has four parameters:
client-id (stored in page item P2_PAYPAL_CLIENT_ID)currency of the transaction (USD)intent (capture payment immediately after the customer makes a payment)enable-funding enables Venmo as a payment optionFor the Demo App, I created a region called 'PayPal'. The important thing to note is the Static Id paypal-button-container. The Static Id will be referenced in the next step.

This step causes the PayPal SDK to render the PayPal buttons in the region we identified. It also sets up code that will be called when the user selects a payment option and code that captures the result of the PayPal transaction in a JSON object. This code is placed in the 'Execute when Page Loads' page property.
You can see the complete code below. Don't be overwhelmed; 90% of the code was lifted directly from the PayPal Integration Builder.
// Capture the Order Total in a JS Variable.
var cartTotal = $v("P2_TOTAL");
const paypalButtonsComponent = paypal.Buttons({
// optional styling for buttons
style: {
color: "gold",
shape: "pill",
layout: "vertical"
},
// Prepare the PayPal transaction with the Order Total
createOrder: (data, actions) => {
const createOrderPayload = {
purchase_units: [
{
amount: {
value: cartTotal
}
}
]
};
return actions.order.create(createOrderPayload);
},
// finalize the transaction, called when user completes payment.
onApprove: (data, actions) => {
const captureOrderHandler = (details) => {
const payerName = details.payer.name.given_name;
// Store the PayPal JSON Response in an APEX Page Item.
$s("P2_PAYPAL_RESPONSE_JSON", JSON.stringify(details, null, 2));
};
return actions.order.capture().then(captureOrderHandler);
},
// handle unrecoverable errors
onError: (err) => {
// Additional Code required here to handle errors from PayPal.
console.error('An error prevented the buyer from checking out with PayPal');
}
});
// Cause PayPal buttons to be rendered.
paypalButtonsComponent
.render("#paypal-button-container")
.catch((err) => {
// Additional Code required here to handle errors rendering PayPal Buttons.
console.error('PayPal Buttons failed to render');
});
With the first three pieces in place, the Checkout page looks something like this:

When the user clicks the 'PayPal' button, the PayPal SDK opens a modal where you can log in as a personal/consumer user. In our case, this is Abby Consumer (consumer@cloudnueva.com). Abby can complete her payment details and complete checkout (as seen in the screenshot below).

The onApprove function is called when the user confirms her payment details. In this function, we can capture the JSON response from PayPal. The JSON response details the PayPal consumer account and the shipping address. We are storing this in the page item "P2_PAYPAL_RESPONSE_JSON". Here is an example response:
{
"id": "13J36569MA8322140",
"intent": "CAPTURE",
"status": "COMPLETED",
"purchase_units": [{
"reference_id": "default",
"amount": {
"currency_code": "USD",
"value": "110.00"
},
"payee": {
"email_address": "merchant@cloudnueva.com",
"merchant_id": "5YWKCLRCZ969U"
},
"shipping": {
"name": {
"full_name": "Abby Consumer"
},
"address": {
"address_line_1": "1 Main St",
"admin_area_2": "San Jose",
"admin_area_1": "CA",
"postal_code": "95131",
"country_code": "US"
}
},
"payments": {
"captures": [{
"id": "0L263272DW1400254",
"status": "COMPLETED",
"amount": {
"currency_code": "USD",
"value": "110.00"
},
"final_capture": true,
"seller_protection": {
"status": "ELIGIBLE",
"dispute_categories": [
"ITEM_NOT_RECEIVED",
"UNAUTHORIZED_TRANSACTION"
]
},
"create_time": "2022-06-21T21:47:54Z",
"update_time": "2022-06-21T21:47:54Z"
}]
}
}],
"payer": {
"name": {
"given_name": "Abby",
"surname": "Consumer"
},
"email_address": "consumer@cloudnueva.com",
"payer_id": "CNVUJBLPTAY4J",
"address": {
"country_code": "US"
}
},
"create_time": "2022-06-21T21:47:45Z",
"update_time": "2022-06-21T21:47:54Z",
"links": [{
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/13J36569MA8322140",
"rel": "self",
"method": "GET"
}]
}
We can then parse the JSON response from step 4 and provide the user with an Order Confirmation.

You can see a list of Payments that have been made in the Sandbox by logging into https://www.sandbox.paypal.com using the Personal/Consumer or Business/Merchant test accounts you created above.
Business/Merchant

Personal/Consumer

Once you have completed your testing, you must take your PayPal App live. To do this, you first need to upgrade your developer account to a business account. The upgrade can be initiated from the 'My Account' menu option at https://developer.paypal.com/
Once you have upgraded your account:

With the introduction of client-side (JavaScript-based) integrations, companies like PayPal and Stripe make it easy to integrate their payment solutions. Adding online payments to your APEX applications has never been easier and is now within reach of most developers.
Credits