Instant Payment Notifications (IPN)

Instant Payment Notifications (IPNs) allow you to receive notifications whenever the state on an object changes (or something important happens to that object).

To set up IPNs for an object, set a callback_uri on that object. Whenever something important happens to the object that we think you should be notified of (typically a state change), we will make an HTTP POST request to your callback_uri with the object_id in the body of the request.

IPN HTTP Request Details

The HTTP request that we make to your callback_uri will have the following characteristics:

  • It will be a POST request.
  • The object_id will be in the body of the request (and not added as a url-parameter).
  • The object_id will be prefixed with the type of object:
  • For checkouts and preapprovals, the reference_id will also be in the body of the request (if a reference_id was set):
  • We will preserve any url-parameters you add to the callback_uri (so you could receive a POST request to

What to do when you receive an IPN

When you receive an IPN, you should use the relevant API call to look up the object’s updated information. For example, if you received an IPN for a checkout, you would receive the checkout_id in the HTTP request POST data. You would then make the /checkout call to look up the new information for the checkout.

IPNs themselves don’t include state information. The canonical source for information about the object is the relevant API call (ex /checkout). We do this so that you don’t have to verify the IPN itself. Because HTTPS/SSL verifies the identity of the server you are making API calls to, you will always know that the updated information you are receiving is correct. If we sent object information in the IPN itself, you would have to verify the authenticity of the information (via signed request, etc). The IPN is only a notification that the state on an object has changed and you should look up the new information.

IPN Batching

We will batch IPNs for the same object that are very close together. So if a checkout goes from state new to authorized to captured immediately, you will only receive one IPN and when you look up the state of the checkout it will be “captured”. The advantage of doing this is that it prevents us from overwhelming your server(s) with HTTP requests and it prevents your app from having to build complicated logic around sequential state changes. Your app should only care about the latest state the object is in.

IPN Failures

If your callback_uri returns a non-200 response code when we make a HTTP request, we will consider the IPN to have failed. If the IPN fails, we will retry at least 6 times:

  • The 1st retry will happen 15 minutes after the initial attempt,
  • the 2nd retry will happen 30 minutes after the 1st retry,
  • the 3rd retry will happen 1 hour after the 2nd retry,
  • the 4th retry will happen 6 hours after the 3rd retry,
  • the 5th retry will happen 12 hours after the 4th retry,
  • and the 6th retry will happen 24 hours after the 5th retry.

Subscription IPNs

If you are using the /preapproval/create call and set auto_recur to true, then we will be creating checkout objects automatically for you every period (month, year, etc). In this case, if you set a callback_uri on the /preapproval/create call, we will send IPNs for the checkouts to that callback_uri.

Account Updater IPNs

WePay sends two different IPNs if you are using Account Updater to automatically update credit cards that have been stored with WePay.

An IPN is sent if a credit card is updated automatically; the credit_card object state remains ‘authorized’, but the card now has new information (last four digits and expiration date). An IPN is sent if a credit card becomes invalid for any reason. The credit_card object state is ‘deleted’.


Testing IPNs on your local machine Please note that in order for IPNs to work, your callback_uri MUST be publicly available. If you are doing development on your local machine it is likely that your callback_uri will not be reachable. Our server cannot connect to localhost!

Withdrawal IPNs

WePay sends IPNs to the account’s callback_uri for that account’s withdrawals. Identify withdrawals by the object identifier in the POST request:


IPN List

Below is a list of IPNs that are associated with each API call.

  • The “Call” column identifies the endpoint to call in order to get information related to the IPN.
  • The “IPN Trigger” column describes the typicall conditions which trigger that IPN.
  • The “Object States” column outlines the object’s state value that can be expected in most cases.
  • The “Additional Parameters” column outlines non-state parameters that should be examined in order to get the relevant updated information about the object.
  • The “Bubbles Up” column illustrates the relationship between the API calls. If callback_uri is not set at a call, it will bubble up to the above layer until it finds a layer with a callback_uri set.
Call IPN Trigger Object States Additional Parameters Bubbles Up
/account account_kyc_requires_documents action_required action_reasons None
account_kyc_verified active None
  • active
  • disabled
  • action_required
  • pending
  • statuses.account_review_status
  • disabled_reasons
blacklist_status_changed disabled disabled_reasons
closed_for_loss disabled disabled_reasons
deleted deleted None
disablement_time_reached disabled disabled_reasons
undeleted active None
/checkout authorized authorized in_review None
review_started_manual authorized in_review
  • failed
  • captured
  • released
  • authorized
captured captured None
failed failed None
  • refunded
  • released
  • refund.amount_refunded
  • refund.refund_reason
new new None
refund_failed released None
reserved authorized None
succeeded released None
/preapproval approved approved None None
cancelled cancelled None
completed completed None
expired expired None
revoked revoked None
retrying retrying None
stopped stopped None
/reports complete complete None None
deleted deleted None
failed failed None
processing processing None
/user deleted deleted None None
registered registered None
/withdrawal captured captured None Account
enter_risk_review started in_review
expired expired None
failed failed None
new new None
  • captured
  • failed
  • started
authorized started in_review