Skip to main content

Statuses

The status is always transmitted as a string - "COMPLETED", not a number. The numeric values found in older integrations are an internal database representation and appear neither in the API nor in webhooks.
WAITING_FOR_EXTERNAL_ACTION is a transient state, set briefly while Paymove finishes processing. It is not terminal and does not mean the payment needs customer action. You may observe it by polling at an unlucky moment - treat it like PENDING.
Note the spelling CANCELED - with a single “l”.

When the webhook arrives

By default Paymove sends a webhook only for the COMPLETED status. Notifications for CANCELED, ERROR or REFUNDED must be enabled by Paymove for your specific product. If you need them, write to integration@paymove.io.
This means that in the default configuration the absence of a webhook does not distinguish a failed payment from one still in progress. If you must detect failed payments, use the status query or ask for full notifications to be enabled.

Webhook payload

The shape depends on whether you set a requestTemplate when registering the webhook.

Without a requestTemplate

Paymove sends the full payment object. Empty fields are omitted, so a given notification may contain fewer of them:
price in this payload is the amount net of the fee, not the amount charged to the customer. Do not use it to verify that the customer paid the right sum - compare against the value you stored when creating the payment.
The payload contains no event or type field and is not wrapped in an envelope. It is a flat object, and you identify the kind of event from the status field.

With a requestTemplate

The payload is exactly what your template renders. For the template {"orderId": "{{externalId}}", "price": "{{price}}"} you receive:
A template can use every field of the default payload - including {{status}}, {{paymentMethod}}, {{email}}, {{date}} and {{orderId}}, not just {{externalId}} and {{price}}. Note that values substituted into a text template arrive in the payload as strings.
A template gives you control over the payload shape and contains exactly what you write into it. If you need to distinguish statuses, add {{status}} to the template or leave requestTemplate unset altogether.

Querying the status

Useful as a supplement to the webhook - for example when the customer is back on returnUrl but the notification has not arrived yet.
This endpoint lives under a different base URL from the rest of the API. It is not routed through gateway-api.sandbox.paymove.io or api.paymove.io - calling it there returns 404 with a text/plain body reading No route found for: GET …, which is not even the standard {status, message} shape.
If no payment exists for the given hash you receive:
paymentHash is not the externalId you passed when creating the payment. It is a value generated by Paymove and returned inside redirectUrl - for example ec6RtwTZKb in https://checkout.sandbox.paymove.io/{productId}?externalId=ec6RtwTZKb. Store it when you create the payment.
This endpoint requires no API key. Do not pass sensitive data to it, and do not treat its response alone as the only proof of payment in critical flows - the trustworthy confirmation is a verified webhook.
  1. Create the payment and store your externalId together with the payment hash from redirectUrl.
  2. Redirect the customer to the checkout.
  3. On the returnUrl page show a “we are processing your payment” message - no fulfilment.
  4. Wait for the webhook, verify its signature and fulfil the order idempotently.
  5. If the webhook has not arrived by the time the customer returns, query the status so you can show the right message immediately.

Refunds

Refunds are handled by Paymove - there is no public API endpoint for issuing them. If you need to refund a payment, contact integration@paymove.io. Once refunded, the payment takes the REFUNDED status.

What’s next

Signature verification

A mandatory step before fulfilling an order.

Webhook configuration

Registering a webhook and assigning it to a product.