diff --git a/.gitignore b/.gitignore index 32d4c58..6155d3d 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,8 @@ generated/ .ballerina **/Config.toml +examples/**/Dependencies.toml + # Ignore Gradle project-specific cache directory .gradle diff --git a/README.md b/README.md index ed42d8b..4ee934e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Ballerina Paypal Orders connector +# Ballerina PayPal Orders connector [![Build](https://github.com/ballerina-platform/module-ballerinax-paypal.orders/actions/workflows/ci.yml/badge.svg)](https://github.com/ballerina-platform/module-ballerinax-paypal.orders/actions/workflows/ci.yml) [![GitHub Last Commit](https://img.shields.io/github/last-commit/ballerina-platform/module-ballerinax-paypal.orders.svg)](https://github.com/ballerina-platform/module-ballerinax-paypal.orders/commits/master) @@ -6,21 +6,119 @@ ## Overview -[//]: # (TODO: Add overview mentioning the purpose of the module, supported REST API versions, and other high-level details.) +[PayPal](https://www.paypal.com/) is a global online payment platform enabling individuals and businesses to securely send and receive money, process transactions, and access merchant services across multiple currencies. + +The `ballerinax/paypal.orders` package provides a Ballerina connector for interacting with the [PayPal Orders API v2](https://developer.paypal.com/docs/api/orders/v2/), allowing you to create, capture, authorize, and manage orders in your Ballerina applications. ## Setup guide -[//]: # (TODO: Add detailed steps to obtain credentials and configure the module.) +To use the PayPal Orders connector, you must have access to a [PayPal Developer account](https://developer.paypal.com/). + +### Step 1: Create a business account + +1. Open the [PayPal Developer Dashboard](https://developer.paypal.com/dashboard). + +2. Click on "Sandbox Accounts" under "Testing Tools". + + ![Sandbox accounts](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.orders/main/docs/setup/resources/sandbox-accounts.png) + +3. Create a Business account + + > Note: Some PayPal options and features may vary by region or country; check availability before creating an account. + + ![Create business account](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.orders/main/docs/setup/resources/create-account.png) + +### Step 2: Create a REST API app + +1. Navigate to the "Apps and Credentials" tab and create a new merchant app. + + Provide a name for the application and select the Business account you created earlier. + + ![Create app](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.orders/main/docs/setup/resources/create-app.png) + +### Step 3: Obtain Client ID and Client Secret + +1. After creating your new app, you will see your **Client ID** and **Client Secret**. Make sure to copy and securely store these credentials. + + ![Credentials](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.orders/main/docs/setup/resources/get-credentials.png) ## Quickstart -[//]: # (TODO: Add a quickstart guide to demonstrate a basic functionality of the module, including sample code snippets.) +To use the `paypal.orders` connector in your Ballerina application, update the `.bal` file as follows: + +### Step 1: Import the module + +Import the `paypal.orders` module. + +```ballerina +import ballerinax/paypal.orders; +``` + +### Step 2: Instantiate a new connector + +1. Create a `Config.toml` file and configure the obtained credentials in the above steps as follows: + +```toml +clientId = "" +clientSecret = "" + +serviceUrl = "" +tokenUrl = "" +``` + +2. Create a `paypal:ConnectionConfig` with the obtained credentials and initialize the connector with it. + +```ballerina +configurable string clientId = ?; +configurable string clientSecret = ?; + +configurable string serviceUrl = ?; +configurable string tokenUrl = ?; +``` + +```ballerina +final paypal:Client paypal = check new ({ + auth: { + clientId, + clientSecret, + tokenUrl + } +}, serviceUrl); +``` + +### Step 3: Invoke the connector operation + +Now, utilize the available connector operations. + +#### Create an order + +```ballerina +public function main() returns error? { + paypal:Order response = check paypal->/orders.post({ + intent: "CAPTURE", + purchase_units: [{ + amount: { + currency_code: "USD", + value: "100.00" + } + }] + }); +} +``` + +### Step 4: Run the Ballerina application + +```bash +bal run +``` ## Examples -The `Paypal Orders` connector provides practical examples illustrating usage in various scenarios. Explore these [examples](https://github.com/module-ballerinax-paypal.orders/tree/main/examples/), covering the following use cases: +The `PayPal Orders` connector provides practical examples illustrating usage in various scenarios. Explore these [examples](https://github.com/ballerina-platform/module-ballerinax-paypal.orders/tree/main/examples/), covering the following use cases: + +1. [**Order lifecycle**](https://github.com/ballerina-platform/module-ballerinax-paypal.orders/tree/main/examples/order-lifecycle): Process a complete PayPal order from creation and updates through confirming and capturing payments. -[//]: # (TODO: Add examples) +2. [**Manage shipping**](https://github.com/ballerina-platform/module-ballerinax-paypal.orders/tree/main/examples/manage-shipping): Enrich an order with shipping details, add or update tracking information, and push shipment updates back to PayPal. ## Build from the source @@ -28,8 +126,8 @@ The `Paypal Orders` connector provides practical examples illustrating usage in 1. Download and install Java SE Development Kit (JDK) version 21. You can download it from either of the following sources: - * [Oracle JDK](https://www.oracle.com/java/technologies/downloads/) - * [OpenJDK](https://adoptium.net/) + - [Oracle JDK](https://www.oracle.com/java/technologies/downloads/) + - [OpenJDK](https://adoptium.net/) > **Note:** After installation, remember to set the `JAVA_HOME` environment variable to the directory where JDK was installed. @@ -39,12 +137,12 @@ The `Paypal Orders` connector provides practical examples illustrating usage in > **Note**: Ensure that the Docker daemon is running before executing any tests. -4. Export Github Personal access token with read package permissions as follows, +4. Export Github Personal access token with read package permissions as follows: - ```bash - export packageUser= - export packagePAT= - ``` + ```bash + export packageUser= + export packagePAT= + ``` ### Build options @@ -88,9 +186,9 @@ Execute the commands below to build from the source. 7. Publish the generated artifacts to the local Ballerina Central repository: - ```bash - ./gradlew clean build -PpublishToLocalCentral=true - ``` + ```bash + ./gradlew clean build -PpublishToLocalCentral=true + ``` 8. Publish the generated artifacts to the Ballerina Central repository: @@ -110,7 +208,7 @@ All the contributors are encouraged to read the [Ballerina Code of Conduct](http ## Useful links -* For more information go to the [`paypal.orders` package](https://central.ballerina.io/ballerinax/paypal.orders/latest). -* For example demonstrations of the usage, go to [Ballerina By Examples](https://ballerina.io/learn/by-example/). -* Chat live with us via our [Discord server](https://discord.gg/ballerinalang). -* Post all technical questions on Stack Overflow with the [#ballerina](https://stackoverflow.com/questions/tagged/ballerina) tag. +- For more information go to the [`paypal.orders` package](https://central.ballerina.io/ballerinax/paypal.orders/latest). +- For example demonstrations of the usage, go to [Ballerina By Examples](https://ballerina.io/learn/by-example/). +- Chat live with us via our [Discord server](https://discord.gg/ballerinalang). +- Post all technical questions on Stack Overflow with the [#ballerina](https://stackoverflow.com/questions/tagged/ballerina) tag. diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index 9e77ec3..85f983f 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -275,9 +275,6 @@ dependencies = [ {org = "ballerina", name = "io"}, {org = "ballerina", name = "jballerina.java"} ] -modules = [ - {org = "ballerina", packageName = "os", moduleName = "os"} -] [[package]] org = "ballerina" @@ -358,7 +355,6 @@ dependencies = [ {org = "ballerina", name = "http"}, {org = "ballerina", name = "lang.runtime"}, {org = "ballerina", name = "log"}, - {org = "ballerina", name = "os"}, {org = "ballerina", name = "test"}, {org = "ballerina", name = "url"}, {org = "ballerina", name = "uuid"}, diff --git a/ballerina/README.md b/ballerina/README.md index 4e54e0b..e650609 100644 --- a/ballerina/README.md +++ b/ballerina/README.md @@ -1,17 +1,115 @@ ## Overview -[//]: # (TODO: Add overview mentioning the purpose of the module, supported REST API versions, and other high-level details.) +[PayPal](https://www.paypal.com/) is a global online payment platform enabling individuals and businesses to securely send and receive money, process transactions, and access merchant services across multiple currencies. + +The `ballerinax/paypal.orders` package provides a Ballerina connector for interacting with the [PayPal Orders API v2](https://developer.paypal.com/docs/api/orders/v2/), allowing you to create, capture, authorize, and manage orders in your Ballerina applications. ## Setup guide -[//]: # (TODO: Add detailed steps to obtain credentials and configure the module.) +To use the PayPal Orders connector, you must have access to a [PayPal Developer account](https://developer.paypal.com/). + +### Step 1: Create a business account + +1. Open the [PayPal Developer Dashboard](https://developer.paypal.com/dashboard). + +2. Click on "Sandbox Accounts" under "Testing Tools". + + ![Sandbox accounts](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.orders/main/docs/setup/resources/sandbox-accounts.png) + +3. Create a Business account + + > Note: Some PayPal options and features may vary by region or country; check availability before creating an account. + + ![Create business account](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.orders/main/docs/setup/resources/create-account.png) + +### Step 2: Create a REST API app + +1. Navigate to the "Apps and Credentials" tab and create a new merchant app. + + Provide a name for the application and select the Business account you created earlier. + + ![Create app](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.orders/main/docs/setup/resources/create-app.png) + +### Step 3: Obtain Client ID and Client Secret + +1. After creating your new app, you will see your **Client ID** and **Client Secret**. Make sure to copy and securely store these credentials. + + ![Credentials](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.orders/main/docs/setup/resources/get-credentials.png) ## Quickstart -[//]: # (TODO: Add a quickstart guide to demonstrate a basic functionality of the module, including sample code snippets.) +To use the `paypal.orders` connector in your Ballerina application, update the `.bal` file as follows: + +### Step 1: Import the module + +Import the `paypal.orders` module. + +```ballerina +import ballerinax/paypal.orders; +``` + +### Step 2: Instantiate a new connector + +1. Create a `Config.toml` file and configure the obtained credentials in the above steps as follows: + +```toml +clientId = "" +clientSecret = "" + +serviceUrl = "" +tokenUrl = "" +``` + +2. Create a `paypal:ConnectionConfig` with the obtained credentials and initialize the connector with it. + +```ballerina +configurable string clientId = ?; +configurable string clientSecret = ?; + +configurable string serviceUrl = ?; +configurable string tokenUrl = ?; +``` + +```ballerina +final paypal:Client paypal = check new ({ + auth: { + clientId, + clientSecret, + tokenUrl + } +}, serviceUrl); +``` + +### Step 3: Invoke the connector operation + +Now, utilize the available connector operations. + +#### Create an order + +```ballerina +public function main() returns error? { + paypal:Order response = check paypal->/orders.post({ + intent: "CAPTURE", + purchase_units: [{ + amount: { + currency_code: "USD", + value: "100.00" + } + }] + }); +} +``` + +### Step 4: Run the Ballerina application + +```bash +bal run +``` ## Examples -The `Paypal Orders` connector provides practical examples illustrating usage in various scenarios. Explore these [examples](https://github.com/module-ballerinax-paypal.orders/tree/main/examples/), covering the following use cases: +The `PayPal Orders` connector provides practical examples illustrating usage in various scenarios. Explore these [examples](https://github.com/ballerina-platform/module-ballerinax-paypal.orders/tree/main/examples/), covering the following use cases: + +1. [**Order lifecycle**](https://github.com/ballerina-platform/module-ballerinax-paypal.orders/tree/main/examples/order-lifecycle): Process a complete PayPal order from creation and updates through confirming and capturing payments. -[//]: # (TODO: Add examples) +2. [**Manage shipping**](https://github.com/ballerina-platform/module-ballerinax-paypal.orders/tree/main/examples/manage-shipping): Enrich an order with shipping details, add or update tracking information, and push shipment updates back to PayPal. diff --git a/ballerina/tests/README.md b/ballerina/tests/README.md new file mode 100644 index 0000000..07e44e5 --- /dev/null +++ b/ballerina/tests/README.md @@ -0,0 +1,63 @@ +# Running Tests + +## Prerequisites + +- OAuth2 credentials (Client ID & Secret) from your PayPal Developer account. + +## Test Environments + +There are two test environments for the PayPal Orders connector tests: + +| Test Group | Environment | +| ------------ | ------------------------------------ | +| `mock_tests` | Mock server for PayPal API (default) | +| `live_tests` | PayPal Sandbox API | + +## Running Tests with the Mock Server + +### Configure the `Config.toml` file + +Create a `Config.toml` file in the `/tests` directory with the following content: + +```toml +isLiveServer = false +``` + +Then, run the following command to run the tests: + +```bash +./gradlew clean test +``` + +## Running Tests with the PayPal Sandbox API + +### Configure the `Config.toml` file + +Create a `Config.toml` file in the `/tests` directory with the following content: + +```toml +isLiveServer = true + +clientId = "" +clientSecret = "" +``` + +Then, run the following command to run the tests: + +```bash +./gradlew clean test +``` + +## Running Specific Groups or Test Cases + +To run only certain test groups or individual test cases, pass the -Pgroups property: + +```bash +./gradlew clean test -Pgroups= +``` + +For example, to run only the mock tests: + +```bash +./gradlew clean test -Pgroups=mock_tests +``` \ No newline at end of file diff --git a/ballerina/tests/tests.bal b/ballerina/tests/tests.bal index d202334..b9d4fce 100644 --- a/ballerina/tests/tests.bal +++ b/ballerina/tests/tests.bal @@ -16,14 +16,13 @@ import ballerina/lang.runtime; import ballerina/log; -import ballerina/os; import ballerina/test; import ballerina/uuid; -configurable boolean isLiveServer = os:getEnv("IS_LIVE_SERVER") == "true"; +configurable boolean isLiveServer = false; -configurable string clientId = os:getEnv("PAYPAL_CLIENT_ID"); -configurable string clientSecret = os:getEnv("PAYPAL_CLIENT_SECRET"); +configurable string clientId = "paypal-client-id"; +configurable string clientSecret = "paypal-client-secret"; final string serviceUrl = isLiveServer ? "https://api-m.sandbox.paypal.com/v2/checkout" : "http://localhost:9090"; final string tokenUrl = isLiveServer ? "https://api-m.sandbox.paypal.com/v1/oauth2/token" : "http://localhost:9444/oauth2/token"; diff --git a/docs/setup/resources/create-account.png b/docs/setup/resources/create-account.png new file mode 100644 index 0000000..18cd5d2 Binary files /dev/null and b/docs/setup/resources/create-account.png differ diff --git a/docs/setup/resources/create-app.png b/docs/setup/resources/create-app.png new file mode 100644 index 0000000..542895f Binary files /dev/null and b/docs/setup/resources/create-app.png differ diff --git a/docs/setup/resources/get-credentials.png b/docs/setup/resources/get-credentials.png new file mode 100644 index 0000000..b43d1b5 Binary files /dev/null and b/docs/setup/resources/get-credentials.png differ diff --git a/docs/setup/resources/sandbox-accounts.png b/docs/setup/resources/sandbox-accounts.png new file mode 100644 index 0000000..5d4606c Binary files /dev/null and b/docs/setup/resources/sandbox-accounts.png differ diff --git a/examples/README.md b/examples/README.md index 55a3484..729efd4 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,30 +1,40 @@ # Examples -The `ballerinax/paypal.orders` connector provides practical examples illustrating usage in various scenarios. +The `ballerinax/paypal.orders` connector provides practical examples illustrating usage in various scenarios. Explore these [examples](https://github.com/ballerina-platform/module-ballerinax-paypal.orders/tree/main/examples), covering use cases such as executing a full order lifecycle - creating, updating, confirming, and capturing payments - as well as enriching orders with shipping details and updating tracking information. -[//]: # (TODO: Add examples) -1. -2. +1. [**Order lifecycle**](https://github.com/ballerina-platform/module-ballerinax-paypal.orders/tree/main/examples/order-lifecycle): Process a complete PayPal order from creation and updates through confirming and capturing payments. + +2. [**Manage shipping**](https://github.com/ballerina-platform/module-ballerinax-paypal.orders/tree/main/examples/manage-shipping): Enrich an order with shipping details, add or update tracking information, and push shipment updates back to PayPal. ## Prerequisites -[//]: # (TODO: Add prerequisites) +1. Generate PayPal OAuth2 credentials to authenticate the connector as described in the [Setup guide](https://github.com/ballerina-platform/module-ballerinax-paypal.orders#setup-guide). + +2. For each example, create a `Config.toml` file with your PayPal configuration. For instance: + +```toml +clientId = "" +clientSecret = "" + +serviceUrl = "https://api.sandbox.paypal.com/v2/checkout" +tokenUrl = "https://api.sandbox.paypal.com/v1/oauth2/token" +``` ## Running an example Execute the following commands to build an example from the source: -* To build an example: +- To build an example: - ```bash - bal build - ``` + ```bash + bal build + ``` -* To run an example: +- To run an example: - ```bash - bal run - ``` + ```bash + bal run + ``` ## Building the examples with the local module @@ -32,14 +42,14 @@ Execute the following commands to build an example from the source: Execute the following commands to build all the examples against the changes you have made to the module locally: -* To build all the examples: +- To build all the examples: - ```bash - ./build.sh build - ``` + ```bash + ./build.sh build + ``` -* To run all the examples: +- To run all the examples: - ```bash - ./build.sh run - ``` + ```bash + ./build.sh run + ``` diff --git a/examples/manage-shipping/Ballerina.toml b/examples/manage-shipping/Ballerina.toml new file mode 100644 index 0000000..af49e33 --- /dev/null +++ b/examples/manage-shipping/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +org = "wso2" +name = "manage_shipping" +version = "0.1.0" +distribution = "2201.12.7" + +[build-options] +observabilityIncluded = true diff --git a/examples/manage-shipping/Manage shipping.md b/examples/manage-shipping/Manage shipping.md new file mode 100644 index 0000000..2804625 --- /dev/null +++ b/examples/manage-shipping/Manage shipping.md @@ -0,0 +1,41 @@ +## Manage shipping + +This use case demonstrates how the PayPal Orders connector can be used to manage shipping tracking information for an order: adding initial tracking details and updating them as shipment status changes. + +## Prerequisites + +### 1. Setup PayPal developer account + +Refer to the [Setup guide](https://central.ballerina.io/ballerinax/paypal.orders/latest#setup-guide) to obtain necessary credentials (Client ID and Client Secret). + +### 2. Configuration + +Create a `Config.toml` file in the example's root directory and add your PayPal credentials related configurations as follows: + +```toml +clientId = "" +clientSecret = "" + +serviceUrl = "https://api.sandbox.paypal.com/v2/checkout" +tokenUrl = "https://api.sandbox.paypal.com/v1/oauth2/token" +``` + +## Run the example + +This example expects two command-line arguments in the following order: + +1. **Order ID**: the ID of the existing order + +2. **Capture ID**: the payment capture ID associated with that order + +Run the example like this (replace with your own IDs): + +```bash +bal run -- +``` + +For instance: + +```bash +bal run -- 1ML724352L2834450 5WA42902XN7717639 +``` \ No newline at end of file diff --git a/examples/manage-shipping/main.bal b/examples/manage-shipping/main.bal new file mode 100644 index 0000000..8768825 --- /dev/null +++ b/examples/manage-shipping/main.bal @@ -0,0 +1,65 @@ +// Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/io; +import ballerina/uuid; +import ballerinax/paypal.orders as paypal; + +configurable string clientId = ?; +configurable string clientSecret = ?; + +configurable string serviceUrl = ?; +configurable string tokenUrl = ?; + +final paypal:Client paypal = check new ({ + auth: { + clientId, + clientSecret, + tokenUrl + } +}, serviceUrl); + +public function main(string orderId, string captureId) returns error? { + string trackingNumber = uuid:createRandomUuid(); + + paypal:Order response = check paypal->/orders/[orderId]/track.post({ + transaction_id: orderId, + capture_id: captureId, + tracking_number: trackingNumber, + status: "NEW", + carrier: "ARAMEX" + }); + + paypal:PurchaseUnit[] purchaseUnits = check response.purchase_units.ensureType(); + + paypal:Tracker[] trackers = check purchaseUnits[0].shipping?.trackers.ensureType(); + + paypal:Tracker tracker = trackers[0]; + + string trackingId = check tracker.id.ensureType(); + + io:println(string `Order(${orderId}) tracking information added (${trackingId})`); + + check paypal->/orders/[orderId]/trackers/[trackingId].patch([ + { + op: "replace", + path: "/status", + value: "CANCELLED" + } + ]); + + io:println(string `Order(${orderId}) tracking information updated`); +} diff --git a/examples/order-lifecycle/Ballerina.toml b/examples/order-lifecycle/Ballerina.toml new file mode 100644 index 0000000..94bc517 --- /dev/null +++ b/examples/order-lifecycle/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +org = "wso2" +name = "order_lifecycle" +version = "0.1.0" +distribution = "2201.12.7" + +[build-options] +observabilityIncluded = true diff --git a/examples/order-lifecycle/Order lifecycle.md b/examples/order-lifecycle/Order lifecycle.md new file mode 100644 index 0000000..20ca090 --- /dev/null +++ b/examples/order-lifecycle/Order lifecycle.md @@ -0,0 +1,29 @@ +## Order lifecycle + +This use case demonstrates how the PayPal Orders connector can be used to process an order from creation through updates, payment authorization, and capture. + +## Prerequisites + +### 1. Setup a PayPal developer account + +Refer to the [Setup guide](https://central.ballerina.io/ballerinax/paypal.orders/latest#setup-guide) to obtain necessary credentials (Client ID and Client Secret). + +### 2. Configuration + +Create a `Config.toml` file in the example's root directory and add your PayPal credentials related configurations as follows: + +```toml +clientId = "" +clientSecret = "" + +serviceUrl = "https://api.sandbox.paypal.com/v2/checkout" +tokenUrl = "https://api.sandbox.paypal.com/v1/oauth2/token" +``` + +## Run the example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/order-lifecycle/main.bal b/examples/order-lifecycle/main.bal new file mode 100644 index 0000000..2c24c9d --- /dev/null +++ b/examples/order-lifecycle/main.bal @@ -0,0 +1,101 @@ +// Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/io; +import ballerinax/paypal.orders as paypal; + +configurable string clientId = ?; +configurable string clientSecret = ?; + +configurable string serviceUrl = ?; +configurable string tokenUrl = ?; + +final paypal:Client paypal = check new ({ + auth: { + clientId, + clientSecret, + tokenUrl + } +}, serviceUrl); + +public function main() returns error? { + paypal:Order createOrderResponse = check paypal->/orders.post({ + intent: "CAPTURE", + purchase_units: [{ + amount: { + currency_code: "USD", + value: "100.00" + } + }] + }); + + string orderId = check createOrderResponse.id.ensureType(); + io:println(string `Order(${orderId}) created`); + + check paypal->/orders/[orderId].patch([ + { + op: "add", + path: "/purchase_units/@reference_id=='default'/amount", + value: { + currency_code: "USD", + value: "200.00", + breakdown: { + item_total: { + currency_code: "USD", + value: "150.00" + }, + shipping: { + currency_code: "USD", + value: "50.00" + } + } + } + } + ]); + + io:println(string `Order(${orderId}) amount updated with breakdown`); + + paypal:Order _ = check paypal->/orders/[orderId]/confirm\-payment\-source.post({ + payment_source: { + card: { + number: "4032037064388131", + expiry: "2035-12" + } + } + }); + + io:println(string `Order(${orderId}) payment source confirmed`); + + paypal:Order orderCaptureResponse = check paypal->/orders/[orderId]/capture.post({ + payment_source: { + card: { + name: "John Doe", + number: "4032037064388131", + expiry: "2035-12" + } + } + }); + + paypal:PurchaseUnit[] purchaseUnits = check orderCaptureResponse.purchase_units.ensureType(); + + paypal:Capture[] captures = check purchaseUnits[0]?.payments?.captures.ensureType(); + + paypal:Capture capture = captures[0]; + + string captureId = check capture.id.ensureType(); + + io:println(string `Order(${orderId}) captured (${captureId})`); +}