Process Payments
At this point merchants have been onboarded, and requirements to enable Payment and Payout capabilities have been met. Now you'll process a Payment from a payer to the merchant's WePay Account. The Clear Payment APIs allow you to build a secure, simple payment flow, and lets you describe different user experience journeys for Payments, Refunds, and Disputes.
As part of the integration, you'll be required to certify your payment processing infrastructure with specific attention to card network rules, NACHA rules and regulations pertaining to ACH and eCheck payments, and security. Use the following guides to ensure that your integration is compliant:
Calculate Fees
First, we'll review how fees work so that you can manage your platform's monetization regardless of the components you use for Payments. Note that the fee-collection method described here is geared towards Blended Rate pricing. Fees will work differently for your platform if you are implementing Merchant IC+ pricing.When you create a Payment, you'll define the total amount of fees that you will collect from it with thefee_amount
parameter. The net (amount
less fee_amount
) will be deposited into your merchant's WePay Account, and the fees will be deposited into your platform's WePay partner account. Next, WePay will debit processing fees from your WePay partner account. This means that when you create a payment and describe fees, the value should be a sum of your platform's fees and WePay's processing fees.Partners on Partner IC+ should calculate fee_amount assuming that fees will never be higher than 2.9% + $0.30
Example: Partners on Blended with Merchants on Blended
As an example, let's say that your contract with WePay has set credit card transaction fees at 3% + $0.30 per transaction. In addition, your platform charges $1.00 per transaction. If you then created a credit card payment for $100.00, you should calculate fees as 3% of theamount
+ $1.30. Thus, the value you would send for the fee_amount
parameter would be 430
.Note that fee amounts are notated in cents, so 430
represents $4.30.The net that your merchant receives will be $95.70, and your platform will receive the full fee amount. WePay will then debit your platform WePay Account for the processing fees agreed to. Following the example above, your platform's net would be $1.00, and WePay would debit $3.30 from you.
Example: Variable + Flat Fee
If the platform wishes to charge a variable + flat fee, (as opposed to just a $1 rate), for example 2.65% + $0.20, It needs to be explicitly stated that if the partner wants to gross 2.65% + $0.20 per transaction, they need to calculate their fee in addition to the WePay fees which get debited from the partner account.
Be sure to review Card Network Rules on fees in order to charge fees in a compliant manner.Use Payment Method Tokens
To immediately create a Payment, we'll send a POST request to the/payments
endpoint. Before we get into the body of the call, we're going to add a Unique-Key
to the header, so that a Payment can't execute twice. The value, of course, can be anything, as long as it's unique.curl -X POST \
--url 'https://stage-api.wepay.com/payments' \
-H 'App-Id: {your-app-id}'\
-H 'App-Token: {your-app-token}'\
-H 'Api-Version: 3.0'\
-H 'Content-Type: application/json'\
-H 'Unique-Key: {generate-a-unique-key}' \
--data-raw '{
"account_id": "{merchant's-account-id}",
"amount": 1000,
"currency": "USD",
"payment_method": {
"token": {
"id": "payment_methods-YOUR-TOKEN-HERE"
},
"credit_card": {
"card_holder": {
"holder_name": "Test Test",
"email": "foo@bar.com",
"address": {
"country": "US",
"postal_code": "94025"
}
}
}
},
“fee_amount”: 200
}'
curl -X POST \
--url 'https://stage-api.wepay.com/payments' \
-H 'App-Id: {your-app-id}'\
-H 'App-Token: {your-app-token}'\
-H 'Api-Version: 3.0'\
-H 'Content-Type: application/json'\
-H 'Unique-Key: {generate-a-unique-key}' \
--data-raw '{
"account_id": "{merchant's-account-id}",
"amount": 1000,
"currency": "USD",
"payment_method": {
"token": {
"id": "payment_methods-YOUR-TOKEN-HERE"
}
}
},
Unique-Key
header, described in our Standard Headers and Idempotency articles. This header is required when creating Payments (POST /payments
) and Refunds (POST /refunds
) in order to protect against duplicate processing. Refer to the Risk Certification guide to identify standard required payment-level rBits and Risk Headers which will allow you to send WePay risk information about the payment. A payment may be flagged for manual risk review in which it is subject to 1-2 business days. The inclusion of payment-level rBits reduces the frequency and duration of manually reviewed payments as well as allows WePay's Risk team to accurately action a payment. Note
POST /payments
request and then a second, identical POST /payments
request with the same Unique-Key
header.Once you execute this call, you'll have successfully created a payment for the amount of $10, with a fee of $2, for a total of $8 going to the merchant. The $2 fee goes to you, as the platform. If it is not specified, the Merchant receives $10 total.
Notes on payments with credit card tokens
- First, we did not add
auto_capture
during tokenization because the default is true. The behavior ofauto_capture
being true means that WePay will execute the payment immediately. If you setauto_capture
to false, you will need to capture it later, see Capture Authorized Payments below. - Second, the
fee_amount
allows the platform to set the fee for processing payment, with a hard limit of 20% of the transaction amount. In the above example, the amount to charge is1000
($10), and the fee is200
($2). We cap the fee at a maximum of 20% of the total amount.201
($2.01) wouldn't work, but199
($1.99) would. - In terms of processing, WePay will take the processing fee from the $2 (the default is 2.9% + $0.30 per transaction, but check with your WePay account manager for the most up to date fees), while the rest is given to your platform.
- Lastly, although providing the cardholder information in both the
POST /payments
andPOST /payment_methods
requests are allowed, it is recommended that the cardholder information is provided in thePOST /payments
request. Providing the cardholder information in both thePOST /payments
andPOST /payment_methods
request will result in aTOKEN_CONFLICT
response error.
This call will also convert the token into a Payment Method ID, which can be stored for future use.
Capture Authorized Payments
The above examples showcase payment flows where payment information is submitted and a payment is executed immediately upon thePOST /payments
call.There are use cases where you'd like to authorize funds, but finalize payment at a later time (item is purchased, but charged when shipped). There are a few different ways to go about this:
Partial capture is only available to US E-commerce platforms.
Note
Manual Capture
By sending thePOST /payments
call with the auto_capture
parameter set to false
, you will delay the payment from moving to an account's available balance by keeping the status
in pending
. Note that the amount in the initial POST /payments
request cannot be changed during capture.Next, make a POST /payments/{id}/capture
request to capture that Payment which will update the API status to completed
. Using the payment ID, a new Unique-key
, and no POST body, the second POST call will look something like thiscurl -X POST \
--url 'https://stage-api.wepay.com/payments/{id}/capture' \
-H 'Accept: application/json' \
-H 'App-Id: {YOUR-APP-ID}' \
-H 'App-Token: {YOUR-APP-TOKEN}' \
-H 'Api-Version: 3.0'\
-H 'Content-Type: application/json' \
-H 'Unique-Key: {NEW-UNIQUE-KEY}' \
Note
completed
, and the funds will become available for Payout.Deferred Capture
First, deferred capture has a few requirements, of which at least one must be met:
- Any deferred capture Payment must be Card Present
- Any deferred capture Payment which is not Card Present must meet one of the following:
- Payment Method is a credit card sent in the
payment_method.credit_card
structure - Payment Method is a tokenized credit card sent in the
payment_method.token
structure
- Payment Method is a credit card sent in the
Deferred capture covers use cases where a card is authorized up-front for an estimated amount, and then the Payment is captured at a designated time. Deferred capture is designed to cover Card Present use cases, but can also be used by PCI compliant platforms where card data is securely stored on your platform's servers.
To schedule a deferred capture payment, send aPOST /payments
request with the capture_at
parameter set with a value of the epoch timestamp of the desired capture time. If the timestamp is in the past, an API error will occur, and the time must be no more than 7 days in the future from the initial POST /payments
request. Your request should look something like this:curl -X POST \
--url 'https://stage-api.wepay.com/payments' \
-H 'Accept: application/json' \
-H 'App-Id: {YOUT-APP-ID}' \
-H 'App-Token: {YOUR-APP-TOKEN}' \
-H 'Api-Version: 3.0'\
-H 'Content-Type: application/json' \
-H 'Unique-Key: {UNIQUE-KEY}' \
--data-raw '{
"capture_at": 1580803200,
"account_id": "abc123",
"amount": 1000,
"currency": "USD",
"fee_amount": 30,
"payment_method": {
"credit_card": {
"auto_update": true,
"card_holder": {
"address": {
"city": "Redwood City",
"country": "US",
"line1": "350 Convention Way",
"postal_code": "94025",
"region": "CA"
},
"email": "example@wepay.com",
"holder_name": "John Snow"
},
"card_number": "5496198584584769",
"cvv": "007",
"expiration_month": 4,
"expiration_year": 2030,
"virtual_terminal_mode": "web",
"card_on_file": true,
"recurring": false
},
"type": "credit_card"
},
"initiated_by": "customer"
}'
pending
status until WePay automatically executes it at the time designated in the capture_at
parameter. At that point, the Payment's status
will either move to completed
.Alternatively, you can manually capture the Payment before the time designated in the capture_at
parameter. To do so, send a POST /payments/{id}/capture
request at the desired capture time. The capture request should look like this:curl -X POST \
--url 'https://stage-api.wepay.com/payments/{id}/capture' \
-H 'Accept: application/json' \
-H 'App-Id: {YOUT-APP-ID}' \
-H 'App-Token: {YOUR-APP-TOKEN}' \
-H 'Api-Version: 3.0' \
-H 'Content-Type: application/json' \
-H 'Unique-Key: {NEW-UNIQUE-KEY}' \
Note
amount
can also be updated up until the capture_at
time.Partial Capture
Another flow you may run into is partial captures, which is only available to US E-commerce platforms. Similar to the authorized payment example above, let's say a payer on your e-commerce platform purchases 2 items from a merchant. If that merchant is only able to ship one item, you can use a partial capture to execute the payment. Unlike capturing authorized payments, which require capturing the full amount, you can capture a partial amount. In the example below, we authorize $60 worth of goods, and partially capture $30 to finish the payment.
Note
While the final capture amount can be less, it cannot be greater than the initial authorized amount.
/payments
:curl -X POST \
--url 'https://stage-api.wepay.com/payments' \
-H 'Accept: application/json' \
-H 'App-Id: {YOUT-APP-ID}'\
-H 'App-Token: {YOUR-APP-TOKEN}' \
-H 'Api-Version: 3.0' \
-H 'Content-Type: application/json' \
-H 'Unique-Key: {UNIQUE-KEY}' \
--data-raw '{
"amount": 6000,
"fee_amount": 300,
"auto_capture": "false",
"currency": "USD",
"account_id": "account-id-here",
"payment_method": {
"token": {
"id": "payment_methods-YOUR-TOKEN-HERE"
}
}
}'
Then, when ready to perform a partial capture, send a follow up call:
curl -X POST \
--url 'https://stage-api.wepay.com/payments/{id}/capture' \
-H 'Accept: application/json'\
-H 'App-Id: {YOUT-APP-ID}'\
-H 'App-Token: {YOUR-APP-TOKEN}'\
-H 'Api-Version: 3.0'\
-H 'Content-Type: application/json'\
-H 'Unique-Key: {NEW-UNIQUE-KEY}' \
--data-raw '{
"amounts": {
"amount": 3000,
"currency": "USD",
"fee_amount": 300
}
}'
ACH
By default, ACH payments take 2 business days (excluding weekends and US holidays) to complete processing and be available to the merchant in acompleted
status. This window typically allows the issuing bank to process the request and send a response back to WePay. If the response from an issuing bank declines the payment and takes longer than 2 business days, then the payment will automatically be refunded.Note
POST /payment_methods
, the last_four
variable that is returned will be the last four numbers of the bank account. However, if you have verified your account via Plaid, this might be the last four numbers of your tokenized bank account number (TAN).CC Token
In order to create a payment which is captured at the time of creation, send aPOST /payments
request like so:{/
Unique-Key
header, described in our Standard Headers and Idempotency articles. This header is required when creating Payments (POST /payments
) and Refunds (POST /refunds
) in order to protect against duplicate processing.Note
POST /payments
request with the same Unique-Key
header.payment_method.updated
topic to be notified when a credit card payment method expires, preemptively avoiding failed future Payments from the same Payer.