diff --git a/README.md b/README.md index e62bf54..90dc859 100644 --- a/README.md +++ b/README.md @@ -6,21 +6,128 @@ ## 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. -## Setup guide +The `ballerinax/paypal.subscriptions` package provides a Ballerina connector for interacting with the [PayPal Subscriptions API v1](https://developer.paypal.com/docs/api/subscriptions/v1/), allowing you to create, manage, and monitor subscription-based billing plans and subscriptions in your Ballerina applications. -[//]: # (TODO: Add detailed steps to obtain credentials and configure the module.) +## Setup Guide + +To use the PayPal Subscriptions 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). + + ![Sandbox accounts](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.subscriptions/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.subscriptions/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. +2. Provide a name for the application and select the Business account created earlier. + ![Create app](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.subscriptions/main/docs/setup/resources/create-app.png) + +### Step 3: Obtain Client ID and Client Secret + +1. After creating the app, you will see your **Client ID** and **Client Secret**. Copy and securely store these credentials. + + ![Credentials](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.subscriptions/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.subscriptions` connector in your Ballerina application, update the `.bal` file as follows: + +### Step 1: Import the Module + +Import the `paypal.subscriptions` module. + +```ballerina +import ballerinax/paypal.subscriptions as paypal; +``` + +### Step 2: Instantiate a New Connector + +1. Create a `Config.toml` file and configure the obtained credentials and URLs: + ```toml + clientId = "" + clientSecret = "" + + serviceUrl = "" + tokenUrl = "" + ``` + +2. Create a `paypal:ConnectionConfig` with the credentials and initialize the connector: + ```ballerina + configurable string clientId = ?; + configurable string clientSecret = ?; + configurable string serviceUrl = ?; + configurable string tokenUrl = ?; + + final paypal:Client paypal = check new ({ + auth: { + clientId, + clientSecret, + tokenUrl + } + }, serviceUrl); + ``` + +### Step 3: Invoke a Connector Operation + +#### Create a Subscription Plan + +```ballerina +public function main() returns error? { + paypal:PlanRequestPOST plan = { + product_id: "PROD-1234567890", + name: "Basic Subscription Plan", + status: "ACTIVE", + billing_cycles: [ + { + frequency: { + interval_unit: "MONTH", + interval_count: 1 + }, + tenure_type: "REGULAR", + sequence: 1, + total_cycles: 0, + pricing_scheme: { + fixed_price: { + value: "10.00", + currency_code: "USD" + } + } + } + ], + payment_preferences: { + auto_bill_outstanding: true, + setup_fee: { + value: "0.00", + currency_code: "USD" + }, + setup_fee_failure_action: "CONTINUE", + payment_failure_threshold: 3 + } + }; + paypal:Plan response = check paypal->/plans.post(plan); +} +``` + +### Step 4: Run the Ballerina application + +```bash +bal run +``` ## Examples -The `Paypal Subscriptions` connector provides practical examples illustrating usage in various scenarios. Explore these [examples](https://github.com/module-ballerinax-paypal.subscriptions/tree/main/examples/), covering the following use cases: +The `PayPal Subscriptions` connector provides practical examples illustrating usage in various scenarios. Explore these [examples](https://github.com/ballerina-platform/module-ballerinax-paypal.subscriptions/tree/main/examples/), covering the following use cases: -[//]: # (TODO: Add examples) +1. [**Create and List Plans**](https://github.com/ballerina-platform/module-ballerinax-paypal.subscriptions/tree/main/examples/create-and-list-plans): Create a subscription plan and list all available plans. +2. [**Monitor and Manage Subscription Status**](https://github.com/ballerina-platform/module-ballerinax-paypal.subscriptions/tree/main/examples/monitor-and-manage-subscription): Retrieve a subscription’s status and suspend or reactivate it based on its state. ## Build from the source @@ -41,11 +148,10 @@ The `Paypal Subscriptions` connector provides practical examples illustrating us 4. Export Github Personal access token with read package permissions as follows, - ```bash - export packageUser= - export packagePAT= - ``` - + ```bash + export packageUser= + export packagePAT= + ``` ### Build options Execute the commands below to build from the source. @@ -62,7 +168,7 @@ Execute the commands below to build from the source. ./gradlew clean test ``` -3. To build the without the tests: +3. To build without the tests: ```bash ./gradlew clean build -x test @@ -88,9 +194,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: @@ -106,11 +212,11 @@ For more information, go to the [contribution guidelines](https://github.com/bal ## Code of conduct -All the contributors are encouraged to read the [Ballerina Code of Conduct](https://ballerina.io/code-of-conduct). +All contributors are encouraged to read the [Ballerina Code of Conduct](https://ballerina.io/code-of-conduct). ## Useful links -* For more information go to the [`paypal.subscriptions` package](https://central.ballerina.io/ballerinax/paypal.subscriptions/latest). +* For more information, go to the [`paypal.subscriptions` package](https://central.ballerina.io/ballerinax/paypal.subscriptions/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/README.md b/ballerina/README.md index aac07d7..83e402a 100644 --- a/ballerina/README.md +++ b/ballerina/README.md @@ -1,17 +1,124 @@ ## 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. -## Setup guide +The `ballerinax/paypal.subscriptions` package provides a Ballerina connector for interacting with the [PayPal Subscriptions API v1](https://developer.paypal.com/docs/api/subscriptions/v1/), allowing you to create, manage, and monitor subscription-based billing plans and subscriptions in your Ballerina applications. -[//]: # (TODO: Add detailed steps to obtain credentials and configure the module.) +## Setup Guide + +To use the PayPal Subscriptions 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). + + ![Sandbox accounts](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.subscriptions/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.subscriptions/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. +2. Provide a name for the application and select the Business account created earlier. + ![Create app](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.subscriptions/main/docs/setup/resources/create-app.png) + +### Step 3: Obtain Client ID and Client Secret + +1. After creating the app, you will see your **Client ID** and **Client Secret**. Copy and securely store these credentials. + + ![Credentials](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.subscriptions/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.subscriptions` connector in your Ballerina application, update the `.bal` file as follows: + +### Step 1: Import the Module + +Import the `paypal.subscriptions` module. + +```ballerina +import ballerinax/paypal.subscriptions as paypal; +``` + +### Step 2: Instantiate a New Connector + +1. Create a `Config.toml` file and configure the obtained credentials and URLs: + ```toml + clientId = "" + clientSecret = "" + + serviceUrl = "" + tokenUrl = "" + ``` + +2. Create a `paypal:ConnectionConfig` with the credentials and initialize the connector: + ```ballerina + configurable string clientId = ?; + configurable string clientSecret = ?; + configurable string serviceUrl = ?; + configurable string tokenUrl = ?; + + final paypal:Client paypal = check new ({ + auth: { + clientId, + clientSecret, + tokenUrl + } + }, serviceUrl); + ``` + +### Step 3: Invoke a Connector Operation + +#### Create a Subscription Plan + +```ballerina +public function main() returns error? { + paypal:PlanRequestPOST plan = { + product_id: "PROD-1234567890", + name: "Basic Subscription Plan", + status: "ACTIVE", + billing_cycles: [ + { + frequency: { + interval_unit: "MONTH", + interval_count: 1 + }, + tenure_type: "REGULAR", + sequence: 1, + total_cycles: 0, + pricing_scheme: { + fixed_price: { + value: "10.00", + currency_code: "USD" + } + } + } + ], + payment_preferences: { + auto_bill_outstanding: true, + setup_fee: { + value: "0.00", + currency_code: "USD" + }, + setup_fee_failure_action: "CONTINUE", + payment_failure_threshold: 3 + } + }; + paypal:Plan response = check paypal->/plans.post(plan); +} +``` + +### Step 4: Run the Ballerina application + +```bash +bal run +``` ## Examples -The `Paypal Subscriptions` connector provides practical examples illustrating usage in various scenarios. Explore these [examples](https://github.com/module-ballerinax-paypal.subscriptions/tree/main/examples/), covering the following use cases: +The `PayPal Subscriptions` connector provides practical examples illustrating usage in various scenarios. Explore these [examples](https://github.com/ballerina-platform/module-ballerinax-paypal.subscriptions/tree/main/examples/), covering the following use cases: -[//]: # (TODO: Add examples) +1. [**Create and List Plans**](https://github.com/ballerina-platform/module-ballerinax-paypal.subscriptions/tree/main/examples/create-and-list-plans): Create a subscription plan and list all available plans. +2. [**Monitor and Manage Subscription Status**](https://github.com/ballerina-platform/module-ballerinax-paypal.subscriptions/tree/main/examples/monitor-and-manage-subscription): Retrieve a subscription’s status and suspend or reactivate it based on its state. diff --git a/ballerina/tests/README.md b/ballerina/tests/README.md index 8befc62..d1aae97 100644 --- a/ballerina/tests/README.md +++ b/ballerina/tests/README.md @@ -3,34 +3,30 @@ ## Prerequisites To run the tests for this PayPal Subscriptions Ballerina connector, you need: -- A PayPal developer account with sandbox credentials (Client ID and Client Secret). -- (Optional) An activated subscription ID for certain live tests. +- A PayPal developer account with sandbox credentials (Client ID and Client Secret). See the [Setup Guide](../README.md#setup-guide) in the main `README.md` for instructions. +- (Optional) An activated subscription ID for `live_active_subscription_tests`. See [docs/ActivateSubscription.md](docs/ActivateSubscription.md) for activation steps. For more information on obtaining credentials, refer to the [PayPal Developer Documentation](https://developer.paypal.com/api/rest/). ---- - ## Test Environments -There are two test environments for running the PayPal Subscriptions connector tests: +There are three test environments for running the PayPal Subscriptions connector tests: -| Test Group | Environment | -| ------------ | --------------------------------------------------- | -| `mock_tests` | Mock server for PayPal Subscriptions API (Default) | -| `live_tests` | PayPal Sandbox API | -| `live_active_subscription_tests`| PayPal Sandbox API (requires active subscription ID) | +| Test Group | Environment | +|-----------------------------------|-------------------------------------------------------| +| `mock_tests` | Mock server for PayPal Subscriptions API (Default) | +| `live_tests` | PayPal Sandbox API | +| `live_active_subscription_tests` | PayPal Sandbox API (requires active subscription ID) | You can run tests in either environment. Each group has its own compatible set of tests. ---- - ## Running Tests in the Mock Server To execute tests on the mock server, ensure that the `isLiveServer` configuration is set to `false` or is unset. You can configure this variable in the `Config.toml` file in the `tests` directory or set it as an environment variable. -### Using a `Config.toml` file +### Using a `Config.toml` File Create a `Config.toml` file in the `tests` directory with the following content: @@ -40,28 +36,15 @@ clientId = "DUMMY_CLIENT_ID" clientSecret = "DUMMY_CLIENT_SECRET" ``` -### Using Environment Variables - -### Linux or macOS - -```bash -export IS_LIVE_SERVER=false -export CLIENT_ID="DUMMY_CLIENT_ID" -export CLIENT_SECRET="DUMMY_CLIENT_SECRET" -``` - -#### Windows +Then, run the following command to run the tests: ```bash -setx IS_LIVE_SERVER false -setx CLIENT_ID DUMMY_CLIENT_ID -setx CLIENT_SECRET DUMMY_CLIENT_SECRET +./gradlew clean test ``` ---- ## Running Tests Against PayPal Sandbox API -### Using a `Config.toml` file +### Using a `Config.toml` File Create a `Config.toml` file in the `tests` directory and add your PayPal sandbox credentials: @@ -79,35 +62,9 @@ Then, run the following command to run the tests: ./gradlew clean test ``` -### Using Environment Variables - -#### Linux or macOS - -```bash -export IS_LIVE_SERVER=true -export CLIENT_ID="" -export CLIENT_SECRET="" -export TEST_ACTIVATED_SUBSCRIPTION_ID="" -``` - -#### Windows - -```bash -setx IS_LIVE_SERVER true -setx CLIENT_ID -setx CLIENT_SECRET -setx TEST_ACTIVATED_SUBSCRIPTION_ID -``` - -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: +To run only certain test groups or individual test cases, pass the `-Pgroups` property: ```bash ./gradlew clean test -Pgroups= @@ -117,4 +74,12 @@ For example, to run only the mock tests: ```bash ./gradlew clean test -Pgroups=mock_tests -``` \ No newline at end of file +``` + +For `live_active_subscription_tests`, obtain an activated subscription ID by following [docs/ActivateSubscription.md](docs/ActivateSubscription.md). + +## Notes + +- The `live_active_subscription_tests` group includes tests like `testUpdateSubscription`, `testReviseSubscription`, `testSuspendSubscription`, `testActivateSubscription`, and `testCancelSubscription`, requiring an active subscription. +- Screenshots for setup and activation are in `docs/resources/`. +- For issues, verify configurations and credentials in the PayPal Developer Dashboard. diff --git a/ballerina/tests/docs/ActivateSubscription.md b/ballerina/tests/docs/ActivateSubscription.md new file mode 100644 index 0000000..6db9670 --- /dev/null +++ b/ballerina/tests/docs/ActivateSubscription.md @@ -0,0 +1,67 @@ +# Activating a Subscription for Live Tests + +The `live_active_subscription_tests` group in `tests.bal` requires an active subscription. After running `testCreateSubscription`, the subscription is created with an `APPROVAL_PENDING` status. This document outlines the steps to manually activate the subscription in the PayPal sandbox environment using a sandbox Personal account. + +## Steps to Activate a Subscription + +1. **Run `testCreateSubscription`**: + - Execute the tests with the `live_tests` group to create a subscription: + ```bash + cd tests + ./gradlew clean test -Pgroups=live_tests + ``` + - The `testCreateSubscription` test logs a response similar to: + ```json + { + "status": "APPROVAL_PENDING", + "id": "I-HNYLYUT5MXYH", + "plan_id": "P-3TF105611V904005MNBRB3ZQ", + "links": [ + { + "href": "https://www.sandbox.paypal.com/webapps/billing/subscriptions?ba_token=BA-90P424234M577033X", + "rel": "approve", + "method": "GET" + }, + ... + ] + } + ``` + - Copy the `href` URL with `rel: "approve"` (e.g., `https://www.sandbox.paypal.com/webapps/billing/subscriptions?ba_token=BA-90P424234M577033X`). + +2. **Obtain Sandbox Personal Account Credentials**: + - Log in to the [PayPal Developer Dashboard](https://developer.paypal.com/dashboard). + - Navigate to "Sandbox Accounts" under "Testing Tools". + ![Sandbox Accounts](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.subscriptions/main/ballerina/tests/docs/resources/sandbox-accounts.png) + - Locate your Personal account (e.g., `xxxx@personal.example.com`). + - Click "View/Edit Account" to see the credentials (email and password). + ![Personal Account Credentials](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.subscriptions/main/ballerina/tests/docs/resources/personal-account-credentials.png) + +3. **Activate the Subscription in the Browser**: + - Open the `approve` URL in a browser. + - You'll be redirected to a PayPal login page. + ![PayPal Login Page](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.subscriptions/main/ballerina/tests/docs/resources/paypal-login-page.png) + - Log in using the sandbox Personal account credentials (e.g., `xxxx@personal.example.com` and password). + - On the "Choose a way to pay" page, select a payment method and click "Continue". + ![Choose Payment Method](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.subscriptions/main/ballerina/tests/docs/resources/choose-payment-method.png) + - Click "Agree and Subscribe" to activate the subscription. + > **Note**: No real funds are used, as this is a sandbox environment. + - You'll be redirected to an example page (e.g., `https://example.com/return`). + ![Example Domain Page](https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-paypal.subscriptions/main/ballerina/tests/docs/resources/example-domain-page.png) + - This confirms the subscription is activated (status changes to `ACTIVE`). + +4. **Update `Config.toml`**: + - Set the `testActivatedSubscriptionId` to the subscription ID from the response (e.g., `I-HNYLYUT5MXYH`): + ```toml + testActivatedSubscriptionId = "I-HNYLYUT5MXYH" + ``` + +5. **Run `live_active_subscription_tests`**: + - Execute the tests for the `live_active_subscription_tests` group: + ```bash + cd tests + ./gradlew clean test -Pgroups=live_active_subscription_tests + ``` + +## Notes +- For issues with activation, verify the `approve` URL and credentials in the PayPal Developer Dashboard. +- Screenshots are stored in `docs/resources/` for reference. diff --git a/ballerina/tests/docs/resources/choose-payment-method.png b/ballerina/tests/docs/resources/choose-payment-method.png new file mode 100644 index 0000000..8ce0156 Binary files /dev/null and b/ballerina/tests/docs/resources/choose-payment-method.png differ diff --git a/ballerina/tests/docs/resources/example-domain-page.png b/ballerina/tests/docs/resources/example-domain-page.png new file mode 100644 index 0000000..3a634fe Binary files /dev/null and b/ballerina/tests/docs/resources/example-domain-page.png differ diff --git a/ballerina/tests/docs/resources/paypal-login-page.png b/ballerina/tests/docs/resources/paypal-login-page.png new file mode 100644 index 0000000..a5b4cad Binary files /dev/null and b/ballerina/tests/docs/resources/paypal-login-page.png differ diff --git a/ballerina/tests/docs/resources/personal-account-credentials.png b/ballerina/tests/docs/resources/personal-account-credentials.png new file mode 100644 index 0000000..9df4786 Binary files /dev/null and b/ballerina/tests/docs/resources/personal-account-credentials.png differ diff --git a/ballerina/tests/docs/resources/sandbox-accounts.png b/ballerina/tests/docs/resources/sandbox-accounts.png new file mode 100644 index 0000000..69d6a36 Binary files /dev/null and b/ballerina/tests/docs/resources/sandbox-accounts.png differ 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/create-and-list-plans/README.md b/examples/create-and-list-plans/README.md new file mode 120000 index 0000000..a1b4861 --- /dev/null +++ b/examples/create-and-list-plans/README.md @@ -0,0 +1 @@ +create-and-list-plans.md \ No newline at end of file diff --git a/examples/monitor-and-manage-subscription/README.md b/examples/monitor-and-manage-subscription/README.md new file mode 120000 index 0000000..57d9a1a --- /dev/null +++ b/examples/monitor-and-manage-subscription/README.md @@ -0,0 +1 @@ +monitor-and-manage-subscription.md \ No newline at end of file