OURPAY keeps checkout, customers, orders, subscriptions, invoices, payments, refunds, disputes, fees, and accounting entries in its own provider-neutral domain. The current deployment exposes PayPal as its payment rail, with every capture collected in one central Business account controlled by the deployment operator. The organization — whether it represents a company or an individual — is currently printed as the invoice issuer by the implementation. OurPay’s confirmed commercial model is merchant-of-record resale; customer documents and provider configuration must be aligned with that role. See Merchant of Record for the remaining work. For direct seller INR receipts and operator-wallet Bitcoin/stablecoin collection, see Domestic and crypto payments. Those rails reuse the same order and invoice flow with their own receiving and confirmation rules.

PayPal account model

PayPal is a first-party integration. OURPAY authenticates with the REST app belonging to the operator Business account that receives all customer money. It does not create Partner Referrals, impersonate sellers, or add a PayPal partner fee. The separately gated PayPal Payouts integration can send to a configured recipient; it is not part of checkout or PayPal multiparty onboarding. Every organization still has a PaymentProcessorAccount so it can enable or disable PayPal and choose its default checkout rail. Those organization-level records all point to the same deployment-managed PayPal credentials. Activating PayPal for an organization authorizes that seller’s checkouts to use the central collection account; it does not connect or settle to the seller’s own PayPal account. This is a central collection arrangement, not PayPal multiparty seller processing. Enabling an organization in OURPAY does not make that organization a PayPal sub-merchant and does not prove that PayPal or a tax authority has approved the operator’s agency arrangement. The deployment operator must obtain the account, contractual, tax, and regulatory approvals required for the countries and products it serves.
OurPay’s reseller model must be supported by processor permissions and consistent customer documents. The current implementation still prints the organization as invoice issuer while a central OurPay account receives PayPal captures. Align the invoice identity, tax configuration, and settlement process before treating a live capture as a completed MoR resale. See PayPal’s Application Guidelines for provider requirements.

Invoice issuer and tax records

Before PayPal can be enabled, the organization must save its legal invoice name and address under Settings → Payment providers → Invoice issuer. This supports company organizations and individual organizations with the same profile:
  • The saved legal name and address appear as the seller on customer invoices and receipts.
  • Optional tax registrations appear below the seller address.
  • Optional invoice notes appear at the bottom of the document.
  • Every document states that payment was collected by OURPAY on behalf of that seller.
  • The PDF author is the organization, while OURPAY remains the document generator and collector.
The generated PDF is the historical artifact. Changing issuer details changes the invoice checksum for a later explicit regeneration; it never silently substitutes OURPAY’s address under the organization’s name. Legacy records without a complete issuer profile can still be read, but a new PayPal activation, re-enable, checkout, or renewal is rejected before money moves. The production deployment is wired to use Numeral as the sole tax calculation and recording provider. It is not active until a valid sk_prod_ key is installed and the Taxes dashboard verifies the live provider account. Once verified, the jurisdiction breakdown is stored on the canonical order, completed sales and refunds are committed with their original event times, and collected tax is excluded from Seller Payable. Numeral supplies nexus and compliance state and, where separately enabled, authorized, and funded, operates registration, filing, and remittance workflows for the legally liable production account. An organization name on the PDF does not by itself transfer tax liability or merchant-of-record status; the invoice model, contracts, processor approvals, and configured Numeral account must identify the same liable party. Set OURPAY_NUMERAL_API_KEY to a production sk_prod_ key on the API, worker, and scheduler. The Taxes dashboard reads registrations and filings directly from Numeral and marks sandbox, misconfigured, or unreachable states as non-production. Tax totals in the OurPay ledger remain accounting records, not filing or payment receipts. Production processes refuse to boot with a sandbox key or a non-Numeral tax path, and a daily audit raises an operational failure for missing provider capabilities, registration gaps, filing approvals, remittance payments, provider problems, or unrecorded tax adjustments.
A PayPal Personal account is not sufficient for a live REST app that accepts payments. Use a verified PayPal Business account. The account must be able to receive the currencies offered by your products.

Supported billing lifecycle

  • One-time card and wallet payments use PayPal Orders v2 and immediate capture.
  • Paid subscription checkouts capture the first payment and save the approved PayPal method.
  • Free trials use a Vault setup token, so no charge is made until the first billing cycle.
  • Renewals use the saved Vault payment token as a merchant-initiated subsequent payment.
  • Full and partial refunds return through the original PayPal capture.
  • PayPal dispute webhooks update the canonical OURPAY dispute and order records.
  • Provider-originated refunds and capture reversals are reconciled even when the operator starts them in PayPal rather than in OURPAY.
  • Capture details store the PayPal payer ID, payer email, and payer name when PayPal supplies them.
  • Every successful checkout follows the normal OURPAY Order, organization-issued invoice number, matching receipt, benefit, ledger, and email pipeline. Initial PayPal orders use the globally unique checkout ID (plus a genuine retry number when needed) as the PayPal purchase-unit invoice ID. Renewals use an ID composed from the OURPAY order ID and the seller-facing invoice number, plus a dunning-attempt suffix after a real failed charge.
  • PayPal’s seller-receivable breakdown remains the authoritative source for processor fees.

Cash versus seller payable

OURPAY deliberately keeps two records that must not be confused:
  • PayPal cash received is the capture’s receivable_amount when PayPal converts currencies, otherwise its net_amount: customer gross minus the PayPal fee and any reported platform fee. That cash belongs to the central operator account until the operator sends a payout.
  • Seller payable is the organization’s internal ledger balance: captured product revenue excluding tax, minus the seller’s configured OURPAY fees, refunds, resolved disputes, and payout transactions, plus any applicable fee credits. Payment processing is included in the OURPAY fee.
OurPay pays the PayPal processing cost and records it separately for reconciliation. It is not an additional seller charge. Provider refund fees and returned processing fees also stay with OurPay for payments with processing included; older payments retain their original fee treatment. PayPal dispute fee debits and credits come from the seller’s fund_movements data. OurPay uses reported amounts instead of guessing from a rate table or the central PayPal account balance. Finance labels the current liability as Seller Payable. A successful capture does not become a seller payable until the canonical order and balance entries exist. Pending captures and free trials contribute zero. Open disputes do not reduce it until they are lost, so the amount can still change. If the operator has already sent money outside OURPAY, that external transfer is not silently treated as a ledger settlement.

Configure PayPal

Create a REST app under the operator PayPal Business account that should receive every payment, then set:
Use sandbox app credentials until the full billing flow passes. Change the environment to live and use that same Business account’s live app credentials only when you are ready to accept real money. The checkout shows secure card fields first and a PayPal button below them. PayPal’s JavaScript SDK opens wallet approval in its popup while the OurPay checkout stays open. Card numbers and security codes go directly to PayPal through hosted fields. The server verifies approval, authentication, captured amount, currency, and fees before fulfilling the order. Closing the popup restores an unpaid checkout; uncertain captures can be checked again without creating another order. A bank may still require a 3D Secure challenge. One-time checkout also shows Apple Pay, Google Pay, Venmo, Pay Later, and PayPal Credit when PayPal and the buyer’s device report eligibility. Apple Pay and Google Pay use their own payment sheets; payment succeeds only after the server confirms capture. The displayed amount is checked again before creating the wallet order. These additional buttons are not offered for subscriptions or saved-method setup; those flows continue to use the supported card and PayPal vault paths. Apple Pay requires domain registration in the PayPal Developer Dashboard. OURPAY serves PayPal’s official live association file at /.well-known/apple-developer-merchantid-domain-association with Content-Type: application/octet-stream. An existing NEXT_PUBLIC_APPLE_DOMAIN_ASSOCIATION override takes precedence. A separate sandbox deployment must set this override to PayPal’s sandbox association file and register its own HTTPS domain. Domain-file hosting alone does not register the domain or grant Apple Pay approval. Google Pay testing requires a Google test wallet with gateway test cards. Venmo requires a US merchant, a US buyer, and USD. In sandbox only, OURPAY passes the checkout billing country as PayPal’s buyer-country test override; live checkout does not override buyer eligibility. See Apple Pay setup, Google Pay setup, and Venmo sandbox testing. Set OURPAY_PAYPAL_CARDS_ENABLED=true only after the receiving Business account has PayPal’s Advanced Credit and Debit Card Payments approval. The browser also checks card eligibility; when cards are unavailable it keeps the PayPal button. Card checkout uses only embedded fields; it never substitutes PayPal’s hosted guest-card page. This is separate from ordinary PayPal wallet or guest card checkout. Merchant country and currency eligibility apply: India is not on the current Advanced card merchant-country list. Keep the flag false until eligibility is confirmed for the actual receiving account. For card subscriptions and free trials, vaulting must also be enabled. Test paid cards, failed and cancelled authentication, free-trial setup, renewal, refunds, and webhook recovery in sandbox before enabling live card payments.
Before replacing credentials from an older connected-seller or partner setup, finish or separately reconcile every existing PayPal order, refund, dispute, and disbursement. The central account’s credentials cannot capture or refund an order owned by a different PayPal merchant account.
Turn on Save payment methods for the REST app and obtain PayPal’s required live approval before setting OURPAY_PAYPAL_VAULTING_ENABLED=true. Set OURPAY_PAYPAL_MERCHANT_ID to the receiving Business account’s merchant ID. Both settings are required before OURPAY exposes saved methods, free trials, merchant-initiated renewals, or subscriptions. One-time payments do not require them.
The merchant ID is the PayPal account ID (payer ID), not the REST app client secret. OURPAY disables vaulting and removes the value from public checkout responses when both settings are identical.
OURPAY labels fixed, undiscounted plans as SUBSCRIPTION_PREPAID. Metered, seat-based, unit-based, custom-priced, or discounted plans use RECURRING_PREPAID, and that consent pattern is stored with the vaulted method and reused on every merchant-initiated renewal. Complex plan terms remain visible in OURPAY checkout; PayPal’s approval screen uses its generic recurring flow where a complete fixed billing-plan representation would be inaccurate. PayPal also requires Risk Data Acquisition for customer-initiated transactions that save a PayPal payment method. OURPAY loads FraudNet on PayPal checkout, generates its per-attempt client metadata ID in the buyer’s browser, and sends that same ID to PayPal when it creates the order or setup token. The checkout Content Security Policy allows PayPal SDK, hosted fields, and FraudNet hosts. Vault and reference-transaction availability is account- and country-dependent, so a successful sandbox flow does not replace PayPal’s live approval. OURPAY_PAYPAL_PAYOUTS_ENABLED defaults to false and should remain false until the operator has PayPal Payouts access and has tested the full compliance and reconciliation flow. When enabled, OURPAY sends to the payout account’s PayPal recipient, records the provider’s payout_item_fee after processing, and debits it from Seller Payable. Returned, refunded, reversed, blocked, denied, or canceled items release the reserved payout exactly once; a provider-reported fee remains a separate seller debit. It does not send to saved Indian bank details. The current seller-payable ledger is denominated in the organization’s account currency (USD in the standard deployment). OURPAY rejects a PayPal checkout in a different currency before charging the customer rather than inventing an exchange rate or overstating what the seller will receive. It also rejects currencies outside PayPal’s published REST-payment set and fractional HUF, JPY, or TWD amounts, which PayPal does not accept. For local or private gateways, OURPAY_PAYPAL_API_BASE_URL can override the PayPal API host. Leave it unset for PayPal sandbox or live.

Webhooks and return URLs

Register this webhook URL on the PayPal REST app, replacing the host with the public OURPAY API host:
Subscribe it to these implemented events:
  • CHECKOUT.ORDER.APPROVED and CHECKOUT.PAYMENT-APPROVAL.REVERSED
  • PAYMENT.CAPTURE.COMPLETED, PAYMENT.CAPTURE.PENDING, PAYMENT.CAPTURE.DECLINED, PAYMENT.CAPTURE.DENIED, PAYMENT.CAPTURE.REFUNDED, and PAYMENT.CAPTURE.REVERSED
  • PAYMENT.REFUND.PENDING and PAYMENT.REFUND.FAILED
  • CUSTOMER.DISPUTE.CREATED, CUSTOMER.DISPUTE.UPDATED, and CUSTOMER.DISPUTE.RESOLVED
  • PAYMENT.PAYOUTS-ITEM.SUCCEEDED, PAYMENT.PAYOUTS-ITEM.FAILED, and other Payouts item lifecycle events when the payout feature is enabled
  • VAULT.PAYMENT-TOKEN.CREATED and VAULT.PAYMENT-TOKEN.DELETED
The order-approved event lets OURPAY capture an approved payment even if the buyer closes the browser before returning. OURPAY verifies every webhook through PayPal’s signature-verification endpoint before durably enqueueing it and ignores duplicate PayPal event IDs. Capture and Vault operations also use stable idempotency keys so an uncertain network response can be retried without intentionally creating a second charge or token. A later dunning attempt uses a new key and a new PayPal order, while a transport retry of the same attempt retains its original key. Checkout and Vault approval calls send these return URLs dynamically:

Enable PayPal for an organization

Open Settings → Payment providers and choose Enable PayPal. OURPAY validates the configured invoice-issuer profile, client ID, and secret, creates or refreshes the direct PayPal processor record, and exposes the capabilities allowed by the deployment configuration. No seller PayPal onboarding redirect is involved. Checkout exposes PayPal only when the organization has an active direct PayPal processor record. Selecting PayPal locks the checkout to that processor before creating an external order or setup token. If a caller requests a payment method that the deployment does not offer, OurPay returns a payment-method-unavailable error instead of silently selecting another rail.

Settlement and reporting

PayPal places captures in the central Business account according to PayPal’s normal availability lifecycle. Finance separately shows the seller payable and the sales, configured fees, refunds, disputes, payer identity, and invoice records behind it. Automatic PayPal seller payouts remain off by default. An approved deployment can enable the PayPal-recipient payout rail; manual bank or PayPal transfers outside that rail are not silently treated as ledger settlement.

Test safely

  1. Use a PayPal sandbox Business account for the REST app and a separate sandbox Personal account as the buyer.
  2. Enable PayPal under Settings → Payment providers.
  3. Complete a one-time checkout and verify the Payment, Order, invoice, receipt, payer metadata, PayPal gross/fee/net breakdown, and seller-payable ledger entries.
  4. Enable Vaulting, then test a paid subscription, a free trial, and at least one automatic renewal.
  5. Exercise full and partial refunds and a dispute.
  6. Replay a webhook event ID and confirm it does not duplicate a payment, fee, order transition, or seller payable.
  7. Confirm pending captures and free trials add no payable, then confirm each successful refund, capture reversal, and lost dispute reduces seller payable exactly once.
  8. Repeat the checklist with low-value live products before opening normal sales.
See PayPal’s official documentation for REST app setup, Orders v2, saved payment methods, Vault setup tokens, and webhook verification.