# PayPal

Take and refund PayPal payments: orders, authorizations and captures, refunds, payouts, invoices and subscriptions.

## Connect PayPal

1. In the sidebar, open **Connections** and press **Add connection**.
2. Type `paypal` and choose **PayPal**.
3. Fill in the fields. Each one says **Required** or **Optional**.
4. Press **Test and save**. GoRunner checks the connection before it saves anything.

The sheet asks for:

- **Client ID · Required**: The REST app’s client ID.
- **Client secret · Required**: The REST app’s secret.
- **Environment · Optional**: Live for real payments, Sandbox for a sandbox app’s credentials.

Sandbox apps have their own credentials.

[Connections](https://docs.gorunner.io/build/connections) says how to sign in again, rename or delete it. In a product that embeds GoRunner, **Add connection** can be missing: then [your provider makes connections](https://docs.gorunner.io/embed/customer-connections) for you.

## Start a workflow

Add a trigger and choose **PayPal**. The trigger uses the same connection as the steps.

### On PayPal Event

Fires when PayPal sends one of the chosen events. Publishing the workflow creates a webhook on the connection's REST app; unpublishing deletes it (an app holds at most 10). Every delivery's signature is checked against PayPal's certificate and this webhook's id; an unsigned or forged one is refused. A redelivery of the same event starts no second run. A sandbox app's credentials (Environment: Sandbox) receive sandbox events only.

- **Events · Required**: Which PayPal events start the workflow. Options: Any event to VAULT.PAYMENT-TOKEN.DELETION-INITIATED (65 options).

A later step can use its data, such as `{{trigger.create_time}}`, `{{trigger.event_type}}`, `{{trigger.id}}` and 3 more. See [Use data from earlier steps](https://docs.gorunner.io/build/use-data-from-earlier-steps).

## Do things in PayPal

Add a **PayPal** step, choose a **Resource**, then an **Operation**. Choose a row to see its fields.

- [Order](https://docs.gorunner.io/apps/paypal#fields-f-order): Create · Get · Update · Capture · Authorize
- [Authorization](https://docs.gorunner.io/apps/paypal#fields-f-authorization): Get · Capture · Void
- [Capture](https://docs.gorunner.io/apps/paypal#fields-f-capture): Get · Refund
- [Refund](https://docs.gorunner.io/apps/paypal#fields-f-refund): Get
- [Payout](https://docs.gorunner.io/apps/paypal#fields-f-payout): Create · Get
- [Payout Item](https://docs.gorunner.io/apps/paypal#fields-f-payoutitem): Cancel · Get
- [Invoice](https://docs.gorunner.io/apps/paypal#fields-f-invoice): Create · Delete · Get · Get Many · Send · Send Reminder · Cancel · Record Payment
- [Subscription](https://docs.gorunner.io/apps/paypal#fields-f-subscription): Create · Get · Update · Activate · Suspend · Cancel
- [Plan](https://docs.gorunner.io/apps/paypal#fields-f-plan): Get · Get Many

Later steps read a step’s output by its name: see [Use data from earlier steps](https://docs.gorunner.io/build/use-data-from-earlier-steps).

## Limits

- A reply from PayPal can be up to 16 MB (a file download can have its own limit). A larger one fails the step; it is never cut short.
- When PayPal says to slow down (429), the step waits as long as it asks, if the step’s time allows. Otherwise it fails and says when to try again.

Not in your list? See [When an app isn’t here](https://docs.gorunner.io/apps/when-an-app-isnt-here#q-not-in-list).

## For developers

In the API, which calls apps pieces, PayPal is `pieceId: "paypal"` with `actionId: "paypal"`, set by `resource` and an `operation_…` field, such as `operation_authorization`. Its trigger is `paypaltrigger` / `paypaltrigger`. [Get an app](https://docs.gorunner.io/api/apps/get-app) returns every field.

It can change something outside the run (`writes_external`). See [How versions and side effects work](https://docs.gorunner.io/apps#q-versions).

### PayPal › Order

### Create

- **Intent · Required**: Take the money once the buyer approves, or hold it. Options: Capture when approved, Authorize, capture later. Default: Capture when approved.
- **Purchase Units · Required**: What is bought, such as [{"amount": {"currency_code": "USD", "value": "100.00"}, "reference_id": "order-1042"}].
- **Payment Source · Optional**: How the buyer pays, such as {"paypal": {"experience_context": {"return_url": "https://shop.example/ok", "cancel_url": "https://shop.example/no"}}}.
- **Additional Fields · Optional**: More of PayPal's fields for the order, as JSON by their API names. The fields above win over the same names here.

### Get, Capture and Authorize

- **Order ID · Required**: The order.

### Update

- **Order ID · Required**: The order.
- **Changes · Required**: A JSON Patch list, such as [{"op": "replace", "path": "/purchase_units/@reference_id=='default'/amount", "value": {"currency_code": "USD", "value": "120.00"}}].

### PayPal › Authorization

### Get and Void

- **Authorization ID · Required**: The authorized payment.

### Capture

- **Authorization ID · Required**: The authorized payment.
- **Amount · Optional**: Decimal text as PayPal writes it, such as 10.00 (JPY and other zero-decimal currencies take no decimals: 1050).
- **Currency · Optional**: Three-letter code in capitals, such as USD, EUR.
- **Final Capture · Optional**: No more captures after this one.
- **Invoice ID · Optional**: Your invoice number, kept on the capture.
- **Note to Payer · Optional**

### PayPal › Capture

### Get

- **Capture ID · Required**: The captured payment.

### Refund

- **Capture ID · Required**: The captured payment.
- **Amount · Optional**: Decimal text as PayPal writes it, such as 10.00 (JPY and other zero-decimal currencies take no decimals: 1050).
- **Currency · Optional**: Three-letter code in capitals, such as USD, EUR.
- **Invoice ID · Optional**
- **Note to Payer · Optional**: Why it is refunded, shown to the buyer.

### PayPal › Refund

### Get

- **Refund ID · Required**: The refund.

### PayPal › Payout

### Create

- **Sender Batch ID · Required**: Your own unique id for the batch: PayPal refuses a second batch with the same id for 30 days, so a repeat never pays twice.
- **Items · Required**: Who is paid, such as [{"recipient_type": "Email", "receiver": "ada@example.com", "amount": {"currency": "USD", "value": "9.87"}, "note": "Thanks!"}].
- **Email Subject · Optional**: The subject of the email recipients get.
- **Email Message · Optional**

### Get

- **Payout Batch ID · Required**: The payout batch.
- **Include Items · Optional**: Empty returns the batch with its items. Options: Only the batch header.

### PayPal › Payout Item

### Cancel and Get

- **Payout Item ID · Required**: One payment of a batch.

### PayPal › Invoice

### Create

- **Detail · Required**: {"currency_code": "USD", "invoice_number": "1042", "note": "Thanks", "payment_term": {"term_type": "NET_30"}}.
- **Invoicer · Optional**: Who bills: {"name": {"given_name", "surname"}, "email_address", "business_name"}.
- **Recipients · Optional**: Who is billed, such as [{"billing_info": {"email_address": "ada@example.com"}}].
- **Items · Optional**: such as [{"name": "Consulting", "quantity": "2", "unit_amount": {"currency_code": "USD", "value": "50.00"}}].
- **Additional Fields · Optional**: More of PayPal's fields for the invoice, as JSON by their API names. The fields above win over the same names here.

### Delete and Get

- **Invoice ID · Required**: The invoice (INV2-…).

### Get Many

- **Return All · Optional**: Read every invoice, page by page (at most 1000; past that the step fails rather than stop early). Off by default.
- **Limit · Optional**: How many invoices to return (1–1000). Default: 50. Shows when **Return All** is off.

### Send and Cancel

- **Invoice ID · Required**: The invoice (INV2-…).
- **Email the Recipient · Optional**: Off marks it sent without an email from PayPal.
- **Subject · Optional**: The email's subject.
- **Note · Optional**: The email's message.

### Send Reminder

- **Invoice ID · Required**: The invoice (INV2-…).
- **Subject · Optional**: The email's subject.
- **Note · Optional**: The email's message.

### Record Payment

- **Invoice ID · Required**: The invoice (INV2-…).
- **Note · Optional**: The email's message.
- **Payment Method · Required**: How it was paid outside PayPal. Options: BANK_TRANSFER, CASH, CHECK, CREDIT_CARD, DEBIT_CARD, PAYPAL, WIRE_TRANSFER, OTHER.
- **Amount · Optional**: Decimal text as PayPal writes it, such as 10.00 (JPY and other zero-decimal currencies take no decimals: 1050).
- **Currency · Optional**: Three-letter code in capitals, such as USD, EUR.
- **Payment Date · Optional**: The day it was paid, such as 2026-11-01.

### PayPal › Subscription

### Create

- **Plan ID · Required**: The plan subscribed to (P-…).
- **Quantity · Optional**: For a plan priced per unit.
- **Start Time · Optional**: When billing starts (RFC 3339). Empty is now.
- **Custom ID · Optional**: Your own reference, kept on the subscription.
- **Subscriber · Optional**: {"name": {"given_name", "surname"}, "email_address"}.
- **Application Context · Optional**: {"return_url", "cancel_url", "brand_name", "user_action": "SUBSCRIBE_NOW"}.

### Get

- **Subscription ID · Required**: The subscription (I-…).

### Update

- **Subscription ID · Required**: The subscription (I-…).
- **Changes · Required**: A JSON Patch list, such as [{"op": "replace", "path": "/purchase_units/@reference_id=='default'/amount", "value": {"currency_code": "USD", "value": "120.00"}}].

### Activate, Suspend and Cancel

- **Subscription ID · Required**: The subscription (I-…).
- **Reason · Optional**: Why (kept on the subscription; at most 128 characters).

### PayPal › Plan

### Get

- **Plan ID · Required**: The plan (P-…).

### Get Many

- **Product ID · Optional**: Only this catalog product's plans.
- **Return All · Optional**: Read every plan, page by page (at most 1000; past that the step fails rather than stop early). Off by default.
- **Limit · Optional**: How many plans to return (1–1000). Default: 50. Shows when **Return All** is off.

Source: https://docs.gorunner.io/apps/paypal
