Skip to main content
MoneyGram is a money-transfer (remittance) API, not a traditional checkout/subscription processor. There’s no customer-object API and no recurring payments — createPayment and createCheckout both run MoneyGram’s full Quote → Update → Commit transfer flow as a single call (MoneyGram has no separate hosted checkout page, so “checkout” here just means the same transfer, mapped onto PayKit’s Checkout shape).

Setup

Required env vars:

How it works

Under the hood this makes 3 calls to MoneyGram’s Transfer API:
  1. POST /transfer/v1/transactions/quote — reserves a transactionId and locks fees/FX for 30 minutes
  2. PUT /transfer/v1/transactions/{id} — attaches the sender/receiver/compliance data from provider_metadata
  3. PUT /transfer/v1/transactions/{id}/commit — actually moves the money
sender and receiver are required on every call — MoneyGram has no customer-object API, so full KYC data must be supplied per-transfer. It doesn’t support customer management or subscriptions.

Checkouts

Same flow, mapped onto Checkout instead of Payment — useful if your code already calls paykit.checkouts. Since Checkout has no top-level amount/currency, both go in provider_metadata too:
checkout.payment_url is a receipt link (valid 5 minutes), not a “go pay here” redirect — the transfer is already committed by the time createCheckout returns. retrieveCheckout/updateCheckout behave the same as retrievePayment/updatePayment below, since MoneyGram has one transaction resource, not separate payment/checkout resources.

Webhooks

MoneyGram doesn’t use a shared secret for webhooks, and publishes exactly one fixed public key per environment (sandbox/production) with no per-partner issuance — so webhookSecret is unused. Pass null:
MoneyGram signs webhooks with an RSA-SHA256 Signature header (t=timestamp, s=signature), verified against the public key above. Since MoneyGram’s TRANSACTION_STATUS_EVENT payload only carries status fields (no amount, sender, or receiver data), this provider re-fetches the full transaction from the Status API before emitting any PayKit event — never trust the webhook body directly. MoneyGram transaction statuses and their PayKit event mappings:
MoneyGram statusPayKit event
UNFUNDEDpayment.created
SENTpayment.succeeded
AVAILABLEpayment.updated
IN_TRANSITpayment.updated
RECEIVEDpayment.updated
DELIVEREDpayment.updated
PROCESSINGpayment.updated
REJECTEDpayment.failed
REFUNDEDrefund.created
CLOSEDpayment.updated

Refunds

This retrieves the transaction for refund eligibility (GET /refund/v2/transactions/{id}), then commits the refund (PUT /refund/v2/transactions/{id}/commit).

Amending a receiver’s name

MoneyGram’s only supported post-commit edit is correcting the receiver’s name (e.g. to match their ID for payout), via updatePayment (or updateCheckout — same behavior, mapped onto Checkout):
Without receiverFirstName/receiverLastName, updatePayment just re-fetches the current transaction.

Unsupported operations

createCustomer, createSubscription, capturePayment, cancelPayment, and deleteCheckout/deletePayment throw ProviderNotSupportedError — MoneyGram has no customer storage, manual capture, recurring transfers, or a way to delete/void a committed transfer. Use createPayment / createCheckout / createRefund directly instead.