{
  "schema": "aaes/capability-pack/1",
  "provider": "paypal",
  "version": "1.0.0",
  "description": "Read PayPal orders and refunds, create orders, and capture approved payments. Order creation can initiate automatic authorization or capture on payer approval; capture responses require checking the payment status.",
  "notes": "Hosts are per environment: PayPal's API reference shows the live host https://api-m.paypal.com and the sandbox host https://api-m.sandbox.paypal.com. This pack registers the live host; a sandbox deployment replaces the host in the endpoint and the egress allowlist in step.\n\nThis pack does not register order authorization, reauthorization or void, and it does not register refund creation (POST /v2/payments/captures/{capture_id}/refund): the reviewed money-moving surface is the order capture below, and refund creation — money moving back to a payer — is a pay capability the deployment adds under the same wording when it needs it.\n\nIt does not register PayPal Payouts, Invoicing, Subscriptions or the v1 APIs. AAES has not been certified by PayPal; the endpoints here are configuration to review and test; the vendor has not endorsed it.",
  "credential": {
    "secret_ref_id": "secret-ref-paypal-oauth-token",
    "custody": "customer_vault",
    "inject": "header",
    "inject_name": "Authorization",
    "note": "An OAuth2 access token for the PayPal REST API, minted with the client-credentials grant (POST https://api-m.paypal.com/v1/oauth2/token; sandbox: https://api-m.sandbox.paypal.com/v1/oauth2/token, HTTP Basic with the deployment's own client ID and secret, grant_type=client_credentials, per PayPal's authentication documentation).\n\nThe client ID and secret stay with an external token process that mints tokens and stores only the complete Authorization header value under this reference — 'Bearer <access_token>', scheme included — refreshing ahead of expiry; neither the executor nor the agent ever sees the client credentials, and this reference must never hold them.\n\nAccess tokens are short-lived: the token response carries expires_in (PayPal's documented sample is roughly nine hours), so the external process mints a replacement rather than letting this reference go stale. Privilege is bounded by the features enabled on the app in the PayPal Developer dashboard — the returned token carries that app's scopes — so the external process uses an app configured with only the access this integration needs; PayPal documents no finer per-token restriction.\n\nTo retire this reference, rotate or remove the client secret in the Developer dashboard so no further tokens can be minted; PayPal documents expiry and re-minting, not individual access-token revocation, so already-minted tokens remain valid until their expires_in elapses. At execution time the resolved material exists in the executor process's memory for the moment of injection only — the deployment owns the executor's memory, log, trace and crash hygiene; the agent never receives it."
  },
  "capabilities": [
    {
      "capability_id": "paypal.orders.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "financial",
      "egress_allowlist": [
        "api-m.paypal.com"
      ],
      "endpoint": "https://api-m.paypal.com/v2/checkout/orders/ORDER_ID",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-paypal-oauth-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "paypal-account",
      "description": "Read one order's record by ID: status, intent, purchase units and payer. ORDER_ID is a placeholder to replace before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "paypal.orders.create",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "financial",
      "egress_allowlist": [
        "api-m.paypal.com"
      ],
      "endpoint": "https://api-m.paypal.com/v2/checkout/orders",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-paypal-oauth-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "pay"
      ],
      "resource_id": "paypal-account",
      "cost_ceiling_usd": 500,
      "description": "Create an order. The caller controls the request body, and creation is not limited to the basic redirect flow: a bare order is created in status CREATED awaiting separate payer approval and capture, but a create call may also supply a payment_source, and the caller-controlled processing_instruction includes ORDER_COMPLETE_ON_PAYMENT_APPROVAL, under which the order auto-completes — authorize or capture depending on the intent — when the payer approves, with no separate capture call (the reference documents PayPal-Request-Id only as an optional idempotency header on this call).\n\nUnrestricted creation can therefore open — and for some configurations complete — a payment workflow for a declared amount, so the action is pay at the minimum R3 tier, and pay is one of the designated actions requiring human approval.\n\nThe registered cost ceiling is a budget control on the declared amount: the gateway refuses a declared amount above it and commits the ceiling against the work budget; it does not bound the amount the provider request encodes — the order's value and currency are the deployment's review.",
      "requires_review": true
    },
    {
      "capability_id": "paypal.orders.capture",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "financial",
      "egress_allowlist": [
        "api-m.paypal.com"
      ],
      "endpoint": "https://api-m.paypal.com/v2/checkout/orders/ORDER_ID/capture",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-paypal-oauth-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "pay"
      ],
      "resource_id": "paypal-account",
      "cost_ceiling_usd": 500,
      "description": "Request capture of payment for an approved order. Inspect the returned capture status before reporting money moved: COMPLETED establishes a completed capture; PENDING can require further action, such as manual acceptance under the payee's receiving preference; DECLINED and other outcomes are possible. A successful HTTP response alone does not establish completion.\n\nThe capability declares pay at R3, which requires human approval. Bind ORDER_ID before enabling. The registered cost ceiling constrains the caller's declared amount; PayPal captures the approved order's amount, which the provider holds, so the ceiling does not necessarily bound what PayPal moves.",
      "requires_review": true
    },
    {
      "capability_id": "paypal.payments.refunds.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "financial",
      "egress_allowlist": [
        "api-m.paypal.com"
      ],
      "endpoint": "https://api-m.paypal.com/v2/payments/refunds/REFUND_ID",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-paypal-oauth-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "paypal-account",
      "description": "Read one refund's record by ID: status, amount and the capture it refunds. REFUND_ID is a placeholder to replace before enabling.",
      "requires_review": true
    }
  ],
  "resources": [
    {
      "resource_id": "paypal-account",
      "kind": "api",
      "locator": "https://api-m.paypal.com",
      "data_class": "financial",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    }
  ],
  "review": {
    "state": "library",
    "date": "2026-09-22",
    "sources": [
      "https://developer.paypal.com/docs/api/orders/v2/ (retrieved 2026-09-21)",
      "https://developer.paypal.com/docs/api/payments/v2/ (retrieved 2026-09-21)",
      "https://developer.paypal.com/api/rest/authentication/ (retrieved 2026-09-21)",
      "https://developer.paypal.com/api/orders/v2/schema.json (retrieved 2026-09-21)"
    ],
    "reviewer_id": "aaes-eng"
  }
}
