Best Practices

Environment Setup


To ensure a successful integration, we recommend you avoid only using your app account for testing. Using APIs to create merchants and their accounts, and charging to these accounts, will lead to a solid understanding of access tokens, app and WePay fees, and both your and your merchants’ account transactions.

Using IPNs


IPNs are a considered a key component of a successful integration. We strongly recommend making use of the callback_uri on every appropriate API call. You can learn more in the IPN reference document.

Merchant Scope


When onboarding a merchant onto your platform, the merchant agrees to allow you to process payments for them. In other words, they grant you a set of permissions. The permissions you want to obtain from your merchants are defined in the “scope” parameter, which is described as a comma-separated list of permissions. This parameter is found in both the /oauth2/authorize and /user/register calls.

It is important to note that either call, used during initial onboarding, is the only opportunity to define the permissions to be requested. To look at it another way, the only way to modify a merchant’s permissions at a later date is to run them through the onboarding process again.

As such, we recommend to ask for all documented permissions up front. Fundamentally, merchants will want you to be able to do everything contained in the permissions. The merchant always has the ability to revoke access but we rarely, if ever, seen an issue in a partner taking this approach to permissions. It is the platform’s prerogative to limit the scope parameter to its immediate need, but please consider the friction it could cause your merchants if you need more permissions as your platform functionality evolves, as you will have to onboard your merchants again.

Recognizable Account Names


This best practice will leverage an excerpt from this article by Visa:

“The merchant name is the single most important factor in cardholder recognition of transactions. Therefore, it is critical that the merchant name, while reflecting the merchant’s “Doing Business As” (DBA) name, also be clearly identifiable to the cardholder.”

Payments made through WePay appear on your cardholder’s statements as WPY*account_name, where account name is defined in the /account/create and /account/modify calls. It is important for you to use easily recognizable and understandable merchant (account) names to avoid confusion, reduce support overhead, and mitigate potential chargebacks resulting from poor information delivery to the cardholder. The following identifies best practices for naming accounts within the parameters available from the card networks:

  • The merchant must be recognizable in the first 14 characters due to limitations imposed by the card networks
  • Many partners successfully use merchant names longer than 14 characters. However, care should be taken to make the first 14 characters understandable in the context of WPY*account_name.
  • The merchant name should not be composed of reference ids or other internal terminology.

Unique ID


This best practice is aimed at eliminating duplicate checkouts and unwanted payment declines by the issuing banks when two or more checkouts occur in rapid succession. This directly affects the experience of the merchants and payers on your platform.

While most API calls are quite harmless if a timeout occurs, others are not. Specifically, a timeout experienced during checkout creation is likely to cause either a missing or duplicate transaction, depending on how errors are processed.

With a synchronous API call, it is difficult to know the stage of the operation when the call results in a timeout. Did the request reach WePay servers? Did WePay’s response timeout on its return? If the call was handled on the server side, how do I retrieve the vital details of the operation?

We’re not going to answer these questions. Instead, we’re going to take a different approach to handling timeouts. Our approach is detailed below:

If you are unsure what happened, run the exact same call again and we will fulfill your original request. You don’t need to be concerned if the object was created or not.

To accomplish this, we will use one additional parameter and introduce a new concept when creating a checkout. This parameter is named “unique_id”, and the concept is called Idempotencey.

Idempotence: the property of certain operations in mathematics and computer science, that can be applied multiple times without changing the result beyond the initial application.

What does all this mean? If you use a new unique_id with each intended checkout creation, recovering from a timeout is as simple as making the exact same call again. To us, the unique_id parameter ensures no two checkout create calls are the same and that they can be uniquely identified in our system. When a checkout create call is accompanied by a unique_id, we check to see if it already exists in our system. If so, we return the information for the existing object. If not, we create the object. Either way, your original request is fulfilled.

Use the following pseudocode to ensure you create unique ids in the correct manner.

response create_checkout(amount, account_id, …) {
	//create the unique_id for this call
	uid = get_GUID()

	loop (some reasonable number of times){
		try {
			// call the /checkout/create endpoint and collect the response
			resp = wepay_checkout_create(uid, amount, account_id);

			// if there is an error in the response, and the error code is 1008
			// and the error message matches this string exactly,
			// then we need to continue through the loop to retry the checkout.
			// If *neither* of these two conditions are met,
			// then we need to return the response
			if (resp['error_code'] != 1008 or resp['error_message'] != "there was an unknown error - please contact for support")
				return resp;
		catch (timeout) {
			// In the event of a timeout, do nothing and go through the loop again
			// to retry the checkout

Note: The unique_id is created at the beginning of the method and keeps its value throughout. Do not extend the functionality of this method to process other types of errors which are remedied by adjusting parameter values. In these circumstances, the unique_id is considered “used” in our system.



There are various fee settings of the /checkout/create call. There are fields to configure, which are amount, app_fee, and fee_payer. The fee_payer parameter has four acceptable values, where the payer, payee (merchant), application, and WePay participate in the transaction to varying degrees. We’ll walk through examples to help showcase how you can think about fees for your app platform.

For the vast majority of use cases, it’s fine to only use a fee_payer value of “payee_from_app”, which, in the context of the other three possibilities, is defined as:

The merchant pays the app_fee and the app platform pays the WePay processing fee.

In this most simple case, there are still four parties involved: the payer, merchant (payee), app platform, and WePay. Let’s step back and look at this simply from the amount and app_fee parameters. With this context, let’s re-examine fee settings:

The payer will pay the amount, the application will receive the app_fee, the remainder will go to the merchant, and the processing_fee will be paid by the application.


To keep the math simple, let’s assume the app platform is paying a 3% WePay fee (“processing_fee”) and every transaction will start with a $100 purchase. Make note of the resulting processing_fee, as it is always calculated against the amount passed in the API call.

Use Case 1: Platform advertises a fee of 4% to merchants.

  • amount = $100.00
  • app_fee= $4.00

The payer will pay the amount of $100, the application will receive the app_fee of $4, the remainder, $96, will go to the merchant, and the processing_fee of $3 will be paid by the application.

Use Case 2: Platform advertises a fee of 4% to the payer.

  • amount = $104.00
  • app_fee= $4.00

The payer will pay the amount of $104, the application will receive the app_fee of $4, the remainder, $100, will go to the merchant, and the processing_fee of $3.12 will be paid by the application.

Use Case 3: Platform advertises a fee of 4% where 3% is paid by the merchant and 1% is paid by the payer.

  • amount = $101.00
  • app_fee= $4.00

The payer will pay the amount ($101), the application will receive the app_fee ($4), the remainder ($97) will go to the merchant, and the processing_fee ($3.03) will be paid by the application.

Since the app_fee calculation is not dependent on the WePay fee, no maintenance is necessary if your WePay fee is adjusted.

This method should address the majority of use cases, but if you feel your situation is unique, please reach out to your WePay account manager for guidance.

Throttle Limits / Batching requests


In an effort to protect all our partners from poor performance, our system uses API throttling. Even the largest of partners rarely need their limits modified, but we do realize, under rare circumstances, exceptions must be made. If you feel you need a higher limit after testing reasonable use cases and implementing batch requests, we’re happy to evaluate your specific situation. You can read more about this in the throttling and batch calls reference pages.

Pre-Launch Checklist


  1. Review any necessary PCI Compliance requirements.
  2. Email and send us your stage and production app ids (client ids) so we can migrate any administrative settings from stage to production.
  3. Perform a final check on your app fee settings.
  4. Perform a final check on your scope settings (OAuth2 or /user/register).
  5. Switch endpoints from stage to production.