# Coinvay Shopify payment adapter · 1.2.0 **Developer source; not an installable Shopify app or theme payment plugin.** Shopify's native Payments Apps platform is invitation-only and requires Payments Partner + payments app review. This package cannot unlock those permissions or become a native checkout option by uploading a ZIP. No Shopify approval, OAuth onboarding or store deployment has been performed. ## Delivered - Persistent SQLite session → Coinvay invoice mapping, stable idempotent order references and exact USD sale validation. - mTLS request guard + HTTPS listener example (no insecure header-only bypass). - Duplicate-body detection and one payable session per Shopify group to avoid multiple chargeable invoices for the same checkout. A retry with a new session ID in an existing group requires manual review. - Authenticated Coinvay invoice lookup before `paymentSessionResolve`; signed webhook adapter; durable resolved state for retries. Uses Payments Apps API version 2026-10. - Disabled-by-default approval/live flags. Even when allowed, this source adapter alone is not a complete compliant payment app. ## Required platform work after approval 1. Apply through Shopify Payments Partner approval. The owner accepts any platform agreements. Obtain restricted `write_payment_gateways` / `write_payment_sessions` scopes through the approved program. 2. Generate the actual app and offsite payment extension with Shopify CLI **after access is granted**. Configure Shopify-issued app IDs, URLs, OAuth callback/install flow, merchant token storage, uninstall/data handling and the extension's actual generated manifest. This bundle intentionally does not invent IDs or a manifest that Shopify has not issued. 3. Wire the generated app's payment-session route to `adapter.start(payload,{authenticatedShop,mtlsAuthorized})`. Verify mTLS with Shopify's current CA chain, not an HTTP header claiming mTLS. Use a trusted public server certificate. Rotate CA/certificates per Shopify documentation. 4. Store tokens and certificates outside source/public folders. Each approved shop needs its own configured adapter/database/key mapping. Never accept the Coinvay API key or Shopify token from customer requests. Configure gateway receiving wallets and match the actual shop's merchant. 5. Wire a separate public HTTPS Coinvay webhook listener to `adapter.webhook(rawBuffer,headers,secret)` (the Shopify listener requires client certificates and cannot receive normal Coinvay callbacks). Also run authenticated reconciliation for unresolved invoices; the adapter exposes `reconcile(invoiceId)` for your scheduler. Enforce request limits and return non-2xx on failed delivery so it retries. 6. Add the complete Shopify buyer-return UI: the example start response opens Coinvay's hosted checkout, which currently has **no store-specific automatic return URL**. Your approved app must present its own checkout/status wrapper and redirect using the Payments Apps API nextAction return URL after confirmed resolution. Do not deploy the example alone as a complete buyer flow. 7. Implement and review rejection/expiry/cancel, refunds, uninstall, reconciliation, support and any capture/void lifecycle required by your approved extension. This adapter supports **USD offsite sale** only; it cannot sign merchant refunds, captures or native auto-debits. 8. Run Shopify's review/test matrix on an approved development store, including duplicate concurrent sessions, delayed crypto settlement, expiry, wrong amounts, shop isolation, test/live segregation and GraphQL throttling. Set live flags only after those tests and platform approval. `mTLS-server.example.mjs` shows the secure payment route wiring but does not implement the other required app routes or OAuth. `config.env.example` contains empty configuration fields. The supplied local tests cover adapter guards, replay mapping and resolver decisions with fixtures; they do not certify Shopify compatibility or approval. Official requirements: https://shopify.dev/docs/apps/build/payments/payments-extension-review mTLS + idempotency: https://shopify.dev/docs/apps/build/payments/considerations Request reference: https://shopify.dev/docs/apps/build/payments/request-reference ## Branding The updated Coinvay logo assets and usage instructions are included in [BRANDING.md](BRANDING.md). Use SVG on supported web surfaces and PNG for native/platform restrictions. ## Original store currency The currency-aware backend uses `currency` with a trusted decimal `amount` when creating a saved order, or integer `cents` in that currency’s minor units when calling the SDK directly (legacy field name). USD is the default for existing records. Example: `{reference:"order-123", amount:"1000.00", currency:"INR", email:"buyer@example.com"}` for `Store.create`; for `Coinvay.create`, use `{reference:"order-123", cents:100000, currency:"INR"}`. The server catalog may set `currency`. The Shopify adapter takes currency only from its authenticated payment session. Coinvay returns USD amount/currency plus originalAmount/originalCurrency and the rate snapshot. Save and compare both source and USD totals before fulfillment. Kit database upgrades add the original currency and locked USD amount without changing old USD orders. Actual FX availability and codes come from /api/currencies. No fiat conversion/remittance is performed. ## Manual or automatic account connection · 1.2.0 Use **Connect to Coinvay** to sign in and authorize this store, or retain manual API-key setup. This release adds separate checkout business name/logo and per-store signed webhooks without changing other stores. Read **CONNECT.md**, included in this package, for exact controls, environment variables, administrator-session integration, encryption/backups, permissions and staging checks. Custom app kits require your existing administrator authentication; Shopify remains subject to platform approval.