Drop-in JavaScript library — like Stripe.js. Redirect customers to hosted checkout from any website.
Overview
spuke.js is a lightweight (~5 KB) browser library. You load it from our CDN, initialise it with a Publishable Key (pk_), and call .checkout() to redirect the customer to the hosted checkout on payments.spuke.com.
No server code required. Works with plain HTML, React, Vue, Svelte, or any framework.
1. Create a Publishable Key
Go to Dashboard → Developers, click New API key, choose Publishable (pk_), and whitelist the domains that are allowed to use it (e.g. mystore.com, *.mystore.com, localhost).
Publishable keys are safe to expose in your frontend — they can only start checkouts for prices that already exist in your catalogue.
The customer is redirected to https://payments.spuke.com/c/… where they complete the payment. On success they land on your success_url with ?session_id=cs_… appended.
The slug in the snippets from Dashboard → Checkout builder only tells spuke which branding profile to apply — the session_id is what makes it a real transaction. Without a valid session, the page falls back to preview mode with dummy data.
3. What the buyer sees
Merchant logo, business name and support email (from Checkout builder).
Line items with product images (line_items[].image_url).
All payment methods enabled for the currency in your plan + Stripe.
3-D Secure / SCA when required.
Success page with spuke-hosted receipt (/r/{merchant_id}/{tx_id}) + PDF.
Preview mode (/c/s/{slug})
Use this URL in your browser to see how your checkout looks with the current Builder settings. It renders a hard-coded sample product for CHF 49.90 and a static list of payment methods. Any ?session=… parameter is ignored — this route never talks to Stripe and never charges anyone.
To test a real payment end-to-end, always create a session via the API first and open /c/{session_id}.
Success & cancel URLs
Optional. When set, spuke redirects the buyer after the session ends and appends ?session_id={id} so you can look up the result.
Customising
Dashboard → Checkout builder controls colours, logo, business name, support email and return URL. Changes apply to every future session — no code changes needed.
The plugin adds spuke as a payment gateway in WooCommerce. It works on classic checkout and Cart/Checkout Blocks, handles both live and test modes, and receives webhooks to reconcile orders even if the buyer closes the tab.
Current version: 1.4.2 — download it from Dashboard → Integrations → WooCommerce.
Requirements
WordPress 6.0+, WooCommerce 6.0+
PHP 7.4+
Non-plain permalinks (needed for the WC REST API)
Install
Dashboard → Integrations → WooCommerce → Download plugin — the ZIP is generated on the fly.
Copy the signing secret into the plugin's Webhook signing secret field. Without it the plugin rejects every incoming call with 401 invalid signature and orders stay pending.
Order flow
Customer places order → WooCommerce calls POST /v1/checkout/sessions with the cart total, currency, and metadata.wc_order_id.
Customer is redirected to checkout_url (spuke hosted checkout).
On success:
spuke redirects the buyer to WooCommerce's return URL.
spuke sends payment.succeeded to /wc-api/spuke.
Plugin verifies the signature (5-minute replay tolerance), matches the order by metadata.wc_order_id, and calls payment_complete().
If the buyer closes the tab, the webhook still completes the order — the redirect is not the source of truth.
Idempotency
The plugin stores the last 50 event.ids per order in post meta (_spuke_events_seen). Duplicate deliveries are skipped without side effects.
Testing
Switch the plugin to Test, place a real order, pay with 4242 4242 4242 4242 (any future expiry, any CVC). The order should move to Processing within a few seconds of the redirect.
Troubleshooting
Symptom
Fix
Gateway not visible at checkout
Confirm the plugin is activated and toggled on in WC → Settings → Payments.
401 invalid signature in server log
Signing secret in plugin ≠ secret shown in dashboard. Regenerate the endpoint and re-paste.
Order stuck at pending after redirect
Webhook URL wrong or blocked by firewall. Test with curl -X POST https://your-store.com/wc-api/spuke -d '{}' — must return 401 (signature missing), not 404.
rest_no_route in WP debug log
Permalinks are set to Plain. Switch to Post name in WP → Settings → Permalinks.
The spukepay module registers spuke as a payment option in PrestaShop. It supports PrestaShop 1.7.6+ and 8.0 – 8.99, works with guest and account checkout, forwards billing & shipping data, product images, and reconciles orders via signed webhooks — even when the buyer closes the tab.
Current version: 1.0.5 — download it from Dashboard → Integrations → PrestaShop.
Requirements
PrestaShop 1.7.6 – 8.99
PHP 7.4+ (8.x recommended)
Friendly URLs enabled (needed for controller routes)
Outbound HTTPS to api.spuke.com
Install
Dashboard → Integrations → PrestaShop → Download module — a fresh spukepay-1.0.5.zip is generated for your account.
Back Office → Modules → Module Manager → Upload a module → pick the ZIP.
After install, click Configure on the spuke tile.
Configure
Field
What to paste
Live API key
An sk_live_... key from Dashboard → Developers → API keys.
Test API key
An sk_test_... key.
Mode
Live in production, Test while integrating.
Webhook signing secret
The whsec_... shown when you create the webhook endpoint below.
Display name
Label shown to customers at checkout (default: spuke).
Register the webhook
In Dashboard → Developers → Webhooks → Add endpoint set:
Copy the signing secret into the module's Webhook signing secret field. Without it every incoming call is rejected with 401 invalid signature and orders stay in Awaiting payment.
Order flow
Customer selects spuke on the payment step → module calls POST /v1/checkout/sessions with cart total, currency, line items (name + image + qty), billing/shipping address, phone, email and metadata.ps_cart_id.
Session state (cart id, secure key, customer id) is persisted in the dedicated {PREFIX}spukepay_session table — no misuse of the global configuration table.
Customer is redirected to spuke Hosted Checkout.
On success:
Buyer is sent to /module/spukepay/validate which auto-refreshes every 6 seconds until the webhook lands.
spuke sends payment.succeeded to /module/spukepay/webhook.
Module verifies HMAC (5-minute replay window), matches the cart via metadata.ps_cart_id, promotes an existing Preparation order to Paid and attaches an OrderPayment.
Terminal states (Paid, Shipped, Delivered) are protected — late expired or canceled events cannot downgrade them.
Refunds
Create a credit slip in the PS back office (Orders → click order → Partial refund / Standard refund). The module hooks actionOrderSlipAdd and calls POST /api-refunds with the exact slip amount (proportional per line item, matching the original discount distribution).
Discounts, rounding & multi-currency
Cart-level discounts are distributed proportionally across line items so Stripe never receives negative amounts.
Rounding drift between PrestaShop's cart total and the summed line items is absorbed on the largest line item (max ±1 minor unit).
Zero-decimal currencies (JPY, KRW, HUF, etc.) are scaled correctly; three-decimal currencies (BHD, JOD, KWD, OMR, TND) send the fractional minor units.
Idempotency
The module stores the last 50 processed event.ids per cart in the spukepay_session row. Duplicate deliveries are dropped without side effects. The Idempotency-Key on create is the PS cart id — retries never create a second Stripe session.
Testing
Switch the module to Test, place a real order, pay with 4242 4242 4242 4242 (any future expiry, any CVC). The order should move to Paid within a few seconds of the redirect. Use 4000 0000 0000 9995 to trigger payment.failed.
Troubleshooting
Symptom
Fix
Payment could not be initialised. Please try again.
The API key is wrong for the selected mode, or the store cannot reach api.spuke.com. Check Back Office → Advanced Parameters → Logs.
Module missing at checkout
Reset the module in Module Manager and check that the currency is enabled in Payment → Preferences → Currency restrictions.
401 invalid signature in server log
Signing secret in module ≠ secret shown in dashboard. Regenerate the endpoint and re-paste.
Order stuck at Awaiting payment
Webhook URL wrong or blocked. curl -X POST https://your-store.com/module/spukepay/webhook -d '{}' must return 401 (signature missing), not 404.
Huge logo on payment step
Older versions shipped the raw logo. Update to 1.0.2+ — the logo is normalised to 124 px width.
Product images missing in the spuke dashboard
Update to 1.0.5+ — earlier versions sent the wrong JSON key.
Chrome asks about "access to other apps and services"
That is the Chrome Payment Handler prompt for Google Pay / Link on a first-seen domain. One-time "Allow" — Chrome remembers it per origin.
Uninstall
Module Manager → spuke → Uninstall. This drops the spukepay_session table and removes all configuration entries. Orders and credit slips are preserved.