External MIT renewals (own billing)

Use web2wave for the first Primer payment only, while your backend charges renewals via Primer MIT. Keep analytics and invoices in sync via webhooks.

By default, web2wave runs a subscription billing engine for Primer: after the first payment, we charge renewals ourselves using vaulted payment methods.

If you want web2wave to handle only the first payment, and your own backend to charge MIT renewals directly via Primer, follow this guide. web2wave will still receive Primer webhooks and create invoices so analytics stay correct.


1. Disable the web2wave billing engine

In Project Settings → Primer, enable Disable billing engine.

This stops web2wave from charging renewals for this project, so you do not get double charges.

The Primer webhook endpoint must still be configured (same as in Primer.io account setup):

https://YOUR_PROJECT_ID.web2wave.com/primer/webhook

Event type: Payment — enable all triggers.


2. Charge renewals from your backend

Create each MIT renewal payment via the Primer API in the same Primer account (same API keys) that is connected to the web2wave project.

Required fields

FieldRequirement
orderIdMust match the original subscription pay_system_id from the first payment (e.g. pr_{priceId}_{ulid}). A new orderId creates a new subscription in web2wave.
customerIdSame as the first payment — the web2wave user_id.
paymentMethodTokenVaulted MULTI_USE token from the first payment.
amount / currencyCodeRenewal amount and currency.
paymentMethod.paymentTypeUsually SUBSCRIPTION. Use UNSCHEDULED for one-off / special phases.

Required metadata

Without these fields, web2wave ignores the webhook:

Metadata keyValue
project_idYour web2wave project ID
client_reference_idweb2wave user_id (same as first payment)
price_idSame price ID as the first payment

Recommended: customer_email, quiz_id, paywall_id.

Example request body

{
  "paymentMethodToken": "<vaulted MULTI_USE token>",
  "amount": 1999,
  "currencyCode": "USD",
  "orderId": "pr_123_01HXYZ...",
  "customerId": "<web2wave_user_id>",
  "paymentMethod": {
    "paymentType": "SUBSCRIPTION"
  },
  "metadata": {
    "project_id": 42,
    "client_reference_id": "<web2wave_user_id>",
    "price_id": 123,
    "customer_email": "[email protected]",
    "quiz_id": 10,
    "paywall_id": 5
  }
}

You can take orderId (pay_system_id), user_id, price_id, and project_id from the subscription after the first payment (web2wave API or your client webhook).


3. What web2wave does next

  1. Primer sends a PAYMENT.STATUS webhook to web2wave.
  2. We match the payment to the existing subscription by orderId.
  3. We create / update the invoice and refresh charges_count, total_revenue, next_charge_date, and status.

No extra “notify web2wave” API call is required — a correctly formed Primer payment is enough.


Common mistakes

  • Different orderId → a duplicate subscription appears in analytics.
  • Missing project_id / client_reference_id / price_id → the webhook is ignored; no invoice is created.
  • Different Primer account (or sandbox vs live mismatch) → signature validation fails or the webhook never reaches web2wave.
  • Billing engine left enabled → web2wave may also charge the renewal (double charge).

📩 Need help? Contact Support