1.1
Buy your plan
Purchase a FinPay plan on this shop. After payment, open My Account to access downloads and licenses.
- You need an active subscription before the ZIP appears.
Guide
Pick your track. Follow one screen at a time — Payment Hub, WP Store, or Custom platform — with comics that match real FinPay screens.
1.1
Purchase a FinPay plan on this shop. After payment, open My Account to access downloads and licenses.
1.2
From My Account → Downloads (or Licenses), download the FinPay plugin package for your release.
1.3
On the WordPress site that will be your Payment Hub, go to Plugins → Add New → Upload Plugin.
1.4
Choose the FinPay ZIP file and click Install Now. Wait until WordPress finishes unpacking.
1.5
Activate the plugin. WooCommerce should already be active on the hub site.
2.1
On first install, open FinPay → Setup. Licensing lives on the Welcome → License wizard step. After the site is locked, use FinPay → License for status, refresh, or deactivate.
2.2
Select Payment hub. This site will own PayPal, the store registry, bridged checkout, and outbound status notify.
2.3
Enter the email and password for your account on this selling shop (LicensePress). That activates the root hub license and locks site_mode to payment.
2.4
When activation succeeds, setup_completed and setup_locked are set. You can mint stores under FinPay → Stores and configure PayPal.
2.5
The hub owns PayPal credentials, the masked catalog, fee rules, and signed status notify. Stores keep the cart, catalog source of truth, and customer emails.
3.1
Open FinPay → Stores on the hub. This is the registry of WooCommerce and custom storefronts (option fpmp_stores).
3.2
Your LicensePress plan limits how many store slots you can mint (for example 7 / 10).
3.3
Use FinPay → Stores → Add store. That claims a LicensePress store slot and creates HMAC credentials. Do not invent store_id or secrets by editing the database.
3.4
Open the store credentials modal and copy the seat token for the WP Store License form. Treat it like a password.
3.5
Copy Payment site URL, Store ID (site_id), API key, and API secret. WP Stores and custom apps use these for signed REST.
3.6
Set platform to wordpress for Woo stores, or custom / laravel / nodejs / etc. for non-WP. Status delivery is HMAC REST for WordPress, signed webhook for other platforms.
4.1
Each store has a credential card on the hub: IDs, secrets, and connection state.
4.2
Rotate API secrets when staff leave or a key may be exposed. Update the store or custom app immediately after.
4.3
Pause a store to stop new sessions without deleting the registry row.
4.4
Disconnect releases the seat back to your plan quota when a storefront is retired.
4.5
Re-mint a seat token if the store site was wiped or the license activation was removed.
5.1
Configure PayPal on the hub — not on each store. Stores bridge checkout to this destination.
5.2
Start in Sandbox. Switch to Live only after a successful test capture and status return.
5.3
Enter Client ID, secret, and merchant identifiers for the selected environment.
5.4
Confirm webhook ID / Orders v2 readiness so captures and status events reach the hub reliably.
5.5
Hub checkout can present hosted fields or buttons. Stores only start the session.
5.6
Sandbox login works, a test order captures, and the origin store receives paid status.
6.1
The hub keeps a processor-facing catalog so PayPal receipts stay clean while stores keep real titles.
6.2
After a store pushes products, SKUs show on the hub catalog for checkout masking.
6.3
Unsynced line items can fall back to global placeholders so checkout still works.
6.4
Masking changes presentation — amounts on line items remain authoritative.
6.5
Periodically review missing masks and stale syncs before a big campaign.
7.1
Masked title, description, and image are what the processor and receipts show — not your raw storefront name.
7.2
Set a clean processor-facing title per SKU on the hub (or via store sync fields).
7.3
Keep descriptions short and consistent so PayPal pages stay tidy.
7.4
Optional mask image for checkout presentation when you do not want the storefront asset exposed.
7.5
Noisy storefront names become structured titles on the hub receipt path.
7.6
Use a naming scheme, avoid PII in masks, and re-sync after major catalog renames.
8.1
Define processing-fee rules on the hub per connected store (enabled, type, value, label, display_mode).
8.2
Stores may send totals.processing_fee as an estimate on orders/create. Set totals.total without that fee. The hub folds tax, shipping, other fees, and the processing fee into one handling line — do not mirror the hub fee back onto the store after pay.
8.3
Stores call POST /fee/info (action fee_info) to cache the resolved fee config before showing cart estimates.
8.4
Some handling / fee behaviors require matching LicensePress plan entitlements.
8.5
Run a sandbox order and confirm the store estimate, hub charged total, and handling line match expectations.
9.1
Customer leaves the storefront, pays on the hub, then returns via your return URL.
9.2
Embed hub checkout in an iframe when you want an in-context experience.
9.3
Allowlist store origins on the hub so iframe embeds are permitted securely.
9.4
Iframe completion may emit fpmp_payment_success or sp_paid for UI. Only signed hub status (HMAC REST or webhook) marks an order paid.
9.5
Choose redirect or iframe per store based on UX and CSP constraints.
10.1
The hub creates an attributed bridged order tied to the origin store.
10.2
After PayPal capture, the hub notifies the origin store right away.
10.3
Status is HMAC-signed (Woo REST) or webhook-signed (custom) so stores can verify authenticity.
10.4
Decline messages travel on the status payload so the origin store can react.
10.5
Customer confirmation email is owned by the originating storefront — not duplicated from the hub.
10.6
Store session → hub PayPal capture → signed paid status → origin order completed.
11.1
Network blips or a down store can delay the first status delivery.
11.2
The hub retries with backoff so temporary outages self-heal.
11.3
Use Order Sync on the hub to manually recover a stuck paid notification.
11.4
Stores must treat duplicate paid notices as safe — never double-fulfill.
11.5
If retries and Order Sync fail, capture logs (HMAC, PayPal, bridge) before contacting support.
12.1
Open WooCommerce → Status → Logs and filter source fpmp. FinPay writes license, PayPal, bridge, and HMAC events there.
12.2
Filter for license, PayPal, bridge, or HMAC failures to narrow the incident.
12.3
Watch for signature mismatch, replay window, rate limit, and non-2xx webhook responses.
12.4
NTP clock skew and missing HTTPS break HMAC and secure cookies — fix hosting first.
12.5
Include timestamps, store ID, hub order id, and the filtered log slice — never paste live secrets.
13.1
FinPay targets modern WooCommerce high-performance order storage on hub and stores.
13.2
Signed requests use a replay window and rate limits — do not retry blindly without new request ids.
13.3
Many stores share one checkout destination. Attribution keeps money and status tied to the origin.
13.4
Seats, PayPal, custom stores, and addons are gated by LicensePress entitlements on the shop.
13.5
Custom integrators: open FinPay → API Guide on the hub, use shortcode [fpmp_api_guide], or the versioned docs synced to My Account Documents.
13.6
Live PayPal, at least one connected store, catalog synced, test paid status, logs clean.
13.7
Continue with the WP Store guide or Custom platform guide from the tabs above.
Track complete
Continue with another track, or open Pricing / My Account when you are ready to buy.
1.1
Install FinPay on the WooCommerce storefront — not on the Payment Hub site.
1.2
Plugins → Add New → Upload Plugin, then choose the FinPay ZIP.
1.3
Click Install Now and wait for WordPress to finish.
1.4
Activate FinPay. WooCommerce must already be active on this store.
1.5
You are about to license this site as a Store with a seat token from the hub.
2.1
In FinPay → Setup (License step), choose Store. The form asks for seat token plus hub connection fields together.
2.2
Paste the seat token from the hub credentials modal, then Payment URL, Store ID, API key, and secret. FinPay validates the seat with LicensePress first, then connects to the hub.
2.3
If the seat is valid, the Store role locks (site_mode = store). If hub connect fails after a good seat, you still land locked as Store with a reconnect warning — fix credentials and Test & Connect.
2.4
Expired, already-used, or wrong-plan seat tokens fail closed. Re-open FinPay → Stores credentials on the hub and copy a fresh seat token if the store was rebuilt.
3.1
Enter the Payment Hub site URL exactly as shown on the hub credential card.
3.2
Paste the Store ID from the hub registry for this storefront.
3.3
Paste key and secret. Keep them server-side and out of theme git repos.
3.4
Use Test & Connect. Health (POST /health) verifies reachability and signing — it does not require a minted license slot. Connect records remote_url and marks the registry connected.
3.5
When connect succeeds, the hub allowlists your host for iframe CSP / redirects. The store can create payment sessions and receive signed /orders/status.
3.6
If the hub rotates secrets, update this screen immediately or sessions will fail.
4.1
Push enabled products so the hub upserts locked managed products. PayPal line names come from mask fields (payload name), while prices stay the store prices.
4.2
Enable sync on products and save, or use bulk sync. The store POSTs /products/sync (action product_sync) with HMAC. Variable products flatten to simple SKUs on the hub.
4.3
Verify managed products appear on the hub (locked for hub-side edits) with the correct _fpmp_store_id attribution.
4.4
Re-sync after price or mask changes you want reflected on the hub pay page.
4.5
Unsynced lines can use a global placeholder (is_global_placeholder) so checkout still works — sync important SKUs before launch.
5.1
Set mask title, description, and image on the store product (synced as name / description / image_url). Never send the raw storefront title as the Payment name.
5.2
Separately, FinPay → Style on the store pushes card_style via /style/sync for the pay iframe chrome and Card Fields shells — not WordPress theme header/footer.
5.3
PayPal and the pay page resolve product_key → masked hub name. Your storefront can keep internal titles.
5.4
Do not put private supplier codes in masks if receipts are customer-visible.
6.1
The store caches fee config from /fee/info and may show a processing-fee estimate so the shopper sees the charged total.
6.2
On orders/create, send totals.processing_fee as the estimate and totals.total without that fee. The hub charges via the handling line — do not add a second store fee after pay.
6.3
If estimates drift, refresh fee/info, re-check hub fee rules and currency, then retest a sandbox order.
7.1
At pay time the store creates a bridged session on the hub (`orders/create`).
7.2
Customer pays on the hub and returns to the store thank-you / order path.
7.3
If enabled, embed hub checkout — ensure CSP allowlisting on the hub.
7.4
Configure success/cancel return URLs so shoppers land correctly after PayPal.
7.5
Money clears on the hub. The store must not invent offline PayPal credentials.
8.1
The Woo order lives on the store. The hub holds the bridged payment attribution.
8.2
Mark paid only after verifying the signed status from the hub — never from browser events.
8.3
Handle decline payloads so the customer can retry without corrupting order state.
8.4
Send order emails from the store after paid status is applied.
8.5
Sandbox: place order → pay on hub → store shows processing/completed → email sent.
9.1
If the store never gets paid, check hub retries and network reachability first.
9.2
Confirm credentials, HTTPS, and that the order is waiting — not already completed.
9.3
Use hub Order Sync to resend status for a known paid bridge.
9.4
Idempotent handlers prevent shipping twice when status is replayed.
10.1
Open WooCommerce → Status → Logs (source fpmp) on the store for connect, sync, and status apply lines.
10.2
Skewed clocks break signatures. Always serve the store over HTTPS in production.
10.3
Trailing spaces, wrong hub URL, or old secrets after rotate are the top failures.
10.4
Collect store ID, approximate time, order id, and redacted logs.
11.1
Keep WooCommerce and FinPay updated for high-performance order storage compatibility.
11.2
Each storefront uses its own seat and credentials against the shared hub.
11.3
If the hub pauses this store, new sessions stop until re-enabled.
11.4
Seat active, hub connected, catalog synced, sandbox paid, emails OK, then flip live gateway on the hub.
11.5
Non-WP storefronts use the Custom platform track instead of this Store license flow.
Track complete
Continue with another track, or open Pricing / My Account when you are ready to buy.
1.1
The Payment hub must be licensed (FinPay → License) and your plan must allow custom stores. PayPal on the hub must be configured (sandbox or live).
1.2
On the hub: FinPay → Stores → Add store. Set platform to custom (or laravel, nodejs, shopify, …). That mints the LicensePress slot and HMAC pair — there is no public self-registration API.
1.3
Save payment_base_url, store_id, api_key, and api_secret only on your backend. Never ship them to browsers or mobile apps.
1.4
Use FinPay → API Guide → Custom on the hub, shortcode [fpmp_api_guide], or the versioned docs synced to My Account Documents.
2.1
All custom→hub calls hit the Payment hub: {payment_base_url}/wp-json/fpmp/v1/…. This is not the LicensePress shop kit base_url (that is only for product license activation inside FinPay).
2.2
Every signed request sets site_id to your Store ID and proves possession of api_secret. Also send X-FPMP-* headers mirroring envelope fields.
2.3
Canonical string: timestamp \n request_id \n site_id \n action \n compact JSON payload. Signature = HMAC-SHA256 hex with api_secret. Empty payload signs as [] (new clients); hub also accepts {}.
2.4
Timestamps must fall within security.replay_window (default 300s). Duplicate request_id is rejected (health exempt). Always mint a fresh request_id.
2.5
Respect per-IP rate limits — backoff instead of hammering create_payment.
3.1
POST /health with action health first. It verifies reachability and signing and does not require a minted license slot.
3.2
POST /connect with site_url (required) and webhook_url (recommended). Connect requires the store to be licensed/minted on the hub — otherwise STORE_KEY_NOT_MINTED / STORE_SLOT_INVALID / LPRESSINT_NOT_LICENSED.
3.3
Persist connection state only after status connected. site_url becomes registry remote_url (CSP frame-ancestors / origin checks).
4.1
POST /products/sync with action product_sync. Default payload is one flat product (required: product_key, name). Optional batch via payload.products[].
4.2
Send masked display as name, description, and image_url — never your real storefront title as name. Prices are real string decimals.
4.3
For unsynced lines, sync a global placeholder once with is_global_placeholder true (hub price $0) and put real prices on create_payment.
4.4
On create_payment, line names are ignored for PayPal — hub resolves product_key → masked name. Item qty/prices and totals stay authoritative.
5.1
POST /fee/info (action fee_info) returns enabled, type, value, label, display_mode. Cache locally for cart estimates.
5.2
Send totals.processing_fee as the estimate; totals.total must exclude that fee. Hub folds it into handling with tax/shipping/other fees — do not put processing fee in totals.fees[].
5.3
Handling addons require matching LicensePress entitlements on the hub license.
6.1
POST /orders/create with action create_payment. Required: token, store_order_id, non-empty items[] (each needs product_key + qty/prices). Also send currency, delivery, return/cancel URLs, customer/addresses, totals.
6.2
Keep product_key aligned with synced catalog. Money as string decimals. Same token + same cart lines reuses the hub session.
6.3
Provide return_url, cancel_url, and store_origin hosts that match your connected site_url host.
6.4
On success, data includes order_id, checkout_url, transaction_id, and charged total/processing_fee. Send the customer to checkout_url.
6.5
Open checkout_url as redirect or iframe (append fpmp_compact=1 for nested embeds). Never invent a local PayPal flow — money clears on the hub.
7.1
Create with delivery iframe, then embed checkout_url. Push pay-iframe styles with style_sync (card_style) — parent CSS only wraps the iframe, not Card Fields inputs.
7.2
Connect records your site_url host for CSP frame-ancestors. Keep store_origin aligned or embeds fail.
7.3
Listen for fpmp_payment_success or sp_paid (verify event.origin). Update UI only — finalize from the signed webhook.
7.4
Test iframe and redirect on mobile browsers before launch. Prefer warm iframe remounts so Card Fields do not reload unnecessarily.
8.1
Payment POSTs a signed envelope to your webhook_url (actions order_status / payment_result). Verify HMAC with the same canonical rules before trusting status.
8.2
Payload includes store_order_id (string), token, status, optional transaction_id, remote_order_id, and decline messages. Source of truth for paid is the webhook — not postMessage.
8.3
Acknowledge with 2xx quickly, then process asynchronously if needed — non-2xx triggers hub backoff retries (fpmp_notify_store).
8.4
Duplicate paid notices must not double-fulfill. Treat PAYMENT_ALREADY_PROCESSED-style outcomes as success.
8.5
Key off the store_order_id you sent at create_payment (string UUID or numeric id).
9.1
Non-2xx responses cause hub backoff retries.
9.2
Hub admins can resend status via Order Sync when your endpoint was down.
9.3
Keep a replay-safe consumer for events you failed to apply locally.
10.1
Usually wrong secret, bad payload canonicalization, or clock skew.
10.2
Sync catalog before blaming checkout when masks look wrong.
10.3
Optimize your endpoint latency; use async workers after 2xx.
10.4
Confirm hub gateway mode matches the credentials your tests expect.
11.1
paypal, custom_stores, and addons must be present on the license resources.
11.2
HTTPS everywhere, secrets in a vault, verify signatures, rotate on leak.
11.3
Cut over hub PayPal to live after end-to-end paid webhook success in sandbox.
11.4
Use the in-product / release API document for field-level contracts — this Guide is the path, not the spec.
11.5
Connect OK, sync OK, create payment OK, webhook paid OK, idempotency OK, live credentials OK.
Track complete
Continue with another track, or open Pricing / My Account when you are ready to buy.