PrestaShop module

Native payment module for PrestaShop 1.7 & 8.x

PrestaShop module

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

  1. Dashboard → Integrations → PrestaShop → Download module — a fresh spukepay-1.0.5.zip is generated for your account.
  2. Back Office → Modules → Module Manager → Upload a module → pick the ZIP.
  3. 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:

  • URL: https://your-store.com/module/spukepay/webhook
  • Events: checkout.session.completed, payment.succeeded, payment.failed, charge.refunded, charge.dispute.created

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

  1. 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.
  2. Session state (cart id, secure key, customer id) is persisted in the dedicated {PREFIX}spukepay_session table — no misuse of the global configuration table.
  3. Customer is redirected to spuke Hosted Checkout.
  4. 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.
  5. 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.