Skip to content
Payment Emulator LabDocumentationOpen console
On this page

Fidelity and limits

PayPal emulator fidelity

Reviewed on 2026-09-06 against the sources indexed by llms/paypal/llm.txt.The implemented surface is Orders v2 and Payments v2 for one purchase unit,one authorization and one final

4 min read

Índice / Index · Español

Reviewed on 2026-09-06 against the sources indexed by llms/paypal/llm.txt. The implemented surface is Orders v2 and Payments v2 for one purchase unit, one authorization and one final capture per order. Other PayPal products in the index are not implied by the gateway's computed implemented status.

#Sources

Official Orders and Payments OpenAPI snapshots are in contracts/paypal/. Adjacent .meta.json files record source URLs, retrieval time and SHA-256 over exact downloaded bytes. Importing a schema does not imply full schema validation.

#Surface

The /paypal API prefix is optional for authenticated requests.

Method Path Behavior
POST /v1/oauth2/token Basic client credentials, form-encoded grant
POST /v2/checkout/orders Create without moving money
GET /v2/checkout/orders/{id} Read order and child payment projections
POST /v2/checkout/orders/{id}/authorize Authorize an approved AUTHORIZE order
POST /v2/checkout/orders/{id}/capture Capture an approved CAPTURE order
GET /v2/payments/authorizations/{id} Read authorization
POST /v2/payments/authorizations/{id}/capture One final full or partial capture
POST /v2/payments/authorizations/{id}/void Release hold; empty HTTP 204
GET /v2/payments/captures/{id} Read capture, including refund status
POST /v2/payments/captures/{id}/refund Full/partial refund; HTTP 201

#What is emulated

  • Application creation and token rotation return clientId, clientSecret and accessToken once. Basic OAuth resolves against the same stored token digest; secrets are never stored in plaintext. Rotation invalidates the previous pair. Existing applications must rotate to obtain their new OAuth pair.
  • Orders without a payment source start as CREATED; orders supplying the PayPal source wait as PAYER_ACTION_REQUIRED. Both return a local buyer link.
  • The buyer approves at /paypal/checkoutnow?token=.... Approval is canonical approved / wire APPROVED, with no debit and no hold. The merchant then authorizes or captures. Calling either before approval is refused.
  • AUTHORIZE creates a hold and returns its own authorization ID. Capture, authorization and order identifiers remain stable on retrieval. Currency and capture-intent mismatches are refused. Child resources are tenant-scoped.
  • A refund returns its individual amount and ID. Replaying its request ID repeats the original response without posting twice. Orders remain COMPLETED after a refund; the child capture becomes PARTIALLY_REFUNDED or REFUNDED.
  • PayPal's own SDK 2.5.0 exercises OAuth, creation and capture. The SDK hardcodes its hosts: the test configures its HTTP adapter to direct traffic exclusively to the local emulator. SDK authentication, serialization and parsing are used unchanged. This is not native base-URL configuration.
  • Webhooks use RSA-SHA256 over transmission ID, timestamp, webhook ID and the unsigned decimal CRC32 of the body. webhookSecret is the local webhook ID for this provider. /paypal/certs/paypal-test.pem serves a public test fixture. An independent Node crypto verification test constructs the manifest using zlib CRC32. The official SDK has no local webhook verifier. The local verifier applies a configurable 300-second replay window.
  • The checkout has a narrow PayPal review layout, a synthetic funding card, approval confirmation and return/cancel links. The return preserves query parameters and adds token and synthetic PayerID. Cancel returns to the merchant without voiding the order. The UI never requests real PayPal credentials.

#What is not emulated

  • OAuth timing and scopes are simplified. Tokens remain valid until application expiry, disabling or rotation. The advertised lifetime does not create a separate expiring OAuth-token collection; scopes are not individually enforced.
  • Only one purchase unit and one final capture are supported. Multiple captures, reauthorization, marketplace routing, item breakdowns, shipping updates and order PATCH are absent; unsupported monetary options are refused explicitly.
  • Refund history has no independent GET resource. Successful refunds are recorded through idempotency and ledger entries; asynchronous refund states and alternative funding sources are not modeled.
  • Webhook bodies are minimal resource stubs. Delivery, RSA signing and local verification work, but complete resource payloads, partial-refund event selection, webhook registration and the remote verification endpoint are not implemented. The bundled certificate and private key are public test fixtures, never PayPal's certificate chain and never suitable for production trust.
  • The buyer flow is a local simulation. No real account login, OTP, JS SDK popup, postMessage protocol, card tokenization, Pay Later, Venmo, vaulting, subscription, invoicing or payout APIs. No exact visual match across regional variants is claimed.
  • Validation is a selected subset. Official snapshots are available locally, but permissive fields and synthetic IDs are not full OpenAPI compatibility. Accounting fees and timing remain configurable synthetic defaults.
Payment Emulator Lab · RonuSoftwareMIT