Build Reporting
We require platforms using the Clear integration to perform reconciliation and other custom reporting. While reporting is only required for Clear integrations, platforms going through Link integrations may also find this guide useful.
Merchants rely on reconciliation reporting in order to match funds collected, failed, refunded, and disputed against funds paid out. Other custom reports that your platform can build out include transaction history reports for your merchants as well as revenue reports for your platform. Here's a guide on how to build out reporting tools leveraging the WePay APIs.
Setup and Reporting Basics
Reporting Notifications
Subscribe to the following notification event topics with a reporting-specific callback URI:accounts.negative_balance
adjustments.created
disputes.created
disputes.funds_withdrawn
disputes.funds_reinstated
disputes.resolved
payments.created
payments.completed
payments.canceled
payouts.created
payouts.completed
payouts.failed
recoveries.created
recoveries.completed
recoveries.failed
refunds.created
refunds.failed
We also recommend using a reporting-specific callback URI on top of normal notification subscriptions so that your platform can automate reporting activity independently of routine information updates and system notifications to your end users.
Reference IDs
WePay API resource IDs are not intended for public consumption. As such, we recommend displaying IDs relevant to your system and utilizing thereference_id
in the WePay API in order to map your system objects to WePay API objects.As an example, you may want to prefix reference IDs with the merchant user ID for your platform. Remember, you can create WePay API objects with a reference ID, or add it later. An entry in your database might look like this:
Platform User ID | WePay Account ID | WePay A Reference ID | WePay Payment ID | WePay P Reference ID |
---|---|---|---|---|
U123 | d3f61e56-5d99-4895-af2d-a07ab48476e9 | U123-9y8435y234 | 21763483-12be-4d07-afe3-ab81a962f3e5 | U123-85981900 |
U123-85981900
in your UI in place of the WePay payment ID, U123-9y8435y234
in place of the WePay account ID, and U123
in place of the WePay legal entity ID. Please keep in mind that the WePay legal entity resource is not a 1:1 translation into a user, and your platform may decide to allow your merchants to create multiple legal entities per platform account.Transaction Records
The Transaction Records API resource will be used heavily in reporting, in conjunction with Notifications. Note that transaction records can take time to build, so the value for the Transaction Record parameters in Notifications may benull
when the Notification is received. Transaction records may be delayed up to 6 hours, so we recommend:- Upon receipt of a Notification, check for Transaction Record IDs. If
null
, move to step 2. - Send a GET request for the resource in question 3 hours after initial receipt of its Notification. If Transaction Record information is still not present, move to step 3:
- Send a GET request for the resource in question 6 hours after the initial receipt of its Notification.
A transaction record contains the following reporting information:
gross_amount
-- The total amount of money moved.net_amount
-- The total amount of money moved, less fees.fee_amount
-- Depending on the owner resource, either platform or WePay fees.currency
-- The currency of the associated transaction.type
-- The type of associated resource (e.g. payment, refund, etc.).owner
-- A structure defining the associated resource's ID and path.
Each transactional resource (payment, refund, payout, etc.) has an associated transaction record which will be returned upon an API request to that resource. Additionally, the platform fee associated with the transaction will have its own transaction record. Here is a breakdown of the transaction record parameters that will appear on different resources:
Resource | Transaction Record Parameters |
---|---|
Payments | txnr_app_fee txnr_merchant |
Refunds | txnr_merchant_refund txnr_app_fee_refund |
Payouts | txnr_payout txnr_failure |
Recoveries | txnr_recovery txnr_failure |
Disputes | txnr_chargeback_app_fees txnr_chargeback_merchant txnr_chargeback_reversal_app_fee txnr_chargeback_reversal_merchant txnr_merchant_chargeback_fee |
Adjustments | txnr_adjustment |
Looking up individual transaction records will help to answer questions about a specific transactional resource, like “Why is the fee on this payment $10.02 instead of $10.01?”
An array of transaction records can be retrieved based on an account or payout ID, as well, which is invaluable to reconciliation and historical reporting. For instance, this request will return an array of transaction records for all transactional resources associated with account IDd3f61e56-5d99-4895-af2d-a07ab48476e9
:GET
curl -X GET \
/transaction_records?account_id=d3f61e56-5d99-4895-af2d-a07ab48476e9 \
-H "App-Id: 121212" \
-H "App-Token: prod_MTAwXzk5OWIwZT666LWYwNWItNDU4MS1iZjBiL" \
-H "Api-Version: 3.0" \
-H "Content-Type: application/json" \
Note
create_time_start
parameter will default to 7 days in the past and the create_time_end
parameter will default to the current time if they are not otherwise specified. Additionally, the interval between create_time_start
and create_time_end
cannot exceed 35 calendar days.Get a Single Payout from Transaction Records
Providing thepayout_id
parameter in a GET/ transactions_records
request will make both the create_time_start
parameter and the create_time_end
not applicable, like mentioned in the above note, and will return the single payout matching the payout_id
.GET
curl -X GET \
/transaction_records?account_id=YOUR_MERCHANT'S_ACCOUNT&payout_id=PAYOUT_ID \
-H "App-Id: 121212" \
-H "App-Token: {YOUR-APP-TOKEN}" \
-H "Api-Version: 3.0" \
-H "Content-Type: application/json" \
Generate Reports
You have a few options to generate reports:
- Generate reports directly from our transaction records
- Generate reports from your payment logs
We'll discuss more about each method later, and the options are not limited to those listed. As we walk through this guide, keep the options and possibilities in mind and decide which method works best for your architecture and system design.
As a platform, you'll need to provide a minimum of three different reports, and other sections of this guide will walk through how to build:
- Merchant transaction history reports
- Merchant reconciliation reports
- Platform revenue reporting
Before going over those specifics, it's important to think through and design your entire reporting system.
Pagination
If your UI provides a time-range filter for merchants to only view transactions from a given time period, include thecreate_time_start
and/or the create_time_end
parameters. For instance, if a merchant elects to view their transaction history from 7/1/2019-7/7/2019 PST, your request body should look like this:GET
curl -X GET \
/transaction_records?account_id=YOUR_MERCHANT'S_ACCOUNT&create_time_start=1561964400&create_time_end=1562482800 \
-H "App-Id: 121212" \
-H "App-Token: prod_MTAwXzk5OWIwZT666LWYwNWItNDU4MS1iZjBiL" \
-H "Api-Version: 3.0" \
-H "Content-Type: application/json" \
previous
and next
parameters which must be used either to paginate the transaction history report, or to fabricate a single continuous report. After the first set of results are returned via the API, send subsequent GET /transaction_records
requests. The only difference from the initial request will be the inclusion of the page
parameter. Here, you will use the value from the next
response parameter that you just received as the value for the page
request parameter you're about to send. For instance, if the response to the initial GET request included ”next”: “/transaction_records?page=cccde123fgh456”
, then your subsequent GET request would look like this:curl -X GET \
/transaction_records?account_id=YOUR_MERCHANT'S_ACCOUNT&create_time_start=1561964400&create_time_end=1562482800&page=cccde123fgh456 \
-H "App-Id: 121212" \
-H "App-Token: prod_MTAwXzk5OWIwZT666LWYwNWItNDU4MS1iZjBiL" \
-H "Api-Version: 3.0" \
-H "Content-Type: application/json" \
page
parameter) precludes customization of the number of results per page; ten results will be returned per page after the initial GET request.Validate Reports
Before and after generating a report, it's best practice to validate your data to ensure reporting accuracy. Using reporting-specific callback URIs enhances your options for sanity checks before sending data to your separate reporting server:
- Validate reporting notifications against your system data
- Validate reporting notifications against our transaction records
Validation against your system data involves building payment data sets based on API logs which get updated upon changes in data. Changes in data can be identified through notifications and GET requests. To validate:
- Compare reporting notifications with your system data before submitting data to your payments database
- Compare a report with your system after generating it
Note
status
of complete
. Similarly, an invoice object should become refunded if:
- Your platform receives a
refunds.created
notification with the relevantpayment.id
, - Or if your platform sends a
GET /payments/id
request where theamount_refunded
parameter has a value greater than 0.
Merchant Reports
Merchants need access to a transaction history for their account(s). Using theGET /transaction_records
request, your platform can automatically pull a collection of this information via the WePay API based on:account_id
payout_id
A request based on your merchant's account ID will look like this:
curl -X GET \
/transaction_records?account_id=YOUR_MERCHANT'S_ACCOUNT \
-H "App-Id: 121212" \
-H "App-Token: prod_MTAwXzk5OWIwZT666LWYwNWItNDU4MS1iZjBiL" \
-H "Api-Version: 3.0" \
-H "Content-Type: application/json" \
Alternatively, you can generate merchant reports based on your own payments data.
Transaction History Reports
1. Generate
As reporting notifications are received, log the details in order of theircreate_time
and look up the transaction records to provide further details to your merchants. This method allows your platform to compile accurate transaction history reports as updates occur, as opposed to polling the WePay API blindly. Suggested transaction history fields to provide in a report include:- Resource type (payment, payout, refund, etc)
- Resource ID
- Time created
- Time updated
- Current status
- Gross
- Net
- Currency
- To/From (e.g. in cases of refunds, a refund will be TO a payer; in cases of payments, a payment will be FROM a payer)
These are basic suggested fields, so keep in mind that your client base may find other fields useful. Consider the available parameters on all transaction-related resources in order to identify the account transaction history information necessary for your platform.
2. Serve and Export
You should give merchants the option of exporting their account transaction history. For instance, most merchants would like to download reports as a .csv file. There are plenty of third party json/.csv converters, or you can build a solution in-house using resources and guides on Stack Overflow.
We also recommend providing basic data tools for your merchants to use. For instance, once a basic report is generated via our transaction records, provide data visualization tools to allow merchants to see their growth, best selling products, chargeback rates, etc. UIs to reorganize and/or pick and choose report columns are also valuable tools.
Reconciliation Reports
Reconciliation reports are required to help merchants understand the contents of their payouts as related to the contents of their accounts.
1. Generate
When apayouts.created
notification is received and followed by a payouts.completed
notification, begin compiling a reconciliation report for that payout by making a GET /transaction_records
request with the payout_id
:curl -X GET \
/transaction_records?payout_id=9c19298b-319e-49f9-aa38-0de8469e7dc1 \ // ID from notification
-H "App-Id: 121212" \
-H "App-Token: prod_MTAwXzk5OWIwZT666LWYwNWItNDU4MS1iZjBiL" \
-H "Api-Version: 3.0" \
-H "Content-Type: application/json" \
The API response will provide an array of all transaction records related to that payout, which you will then parse into consumable reports. Suggested reconciliation report fields to include:
- Payout ID
- Payout date
- Resource type (payment, refund, etc)
- Resource ID
- Gross - The total amount of the transaction
- Fees - The total amount of the transaction associated with your app Account balance
- Net - The total amount of the transaction associated with the merchant Account balance
Note that the credit / debit value of the amount fields will change depending on the resource. For instance, if a transaction record is examining a Payment, the gross indicates a debit from the payer, the net indicates a credit to the merchant, and the fee indicates a credit to your app account. For merchant reporting purposes, indicate credits and debits relative to the merchant Account balance. So, in the case of a Payment, the gross and net should be credits and the fee should be a debit.
Info
Validation for reconciliation reports is not necessary, as your platform will not have the ability to predict the resources included in a payout. Because we control payout limits, manual reviews, and other factors impacting the contents of payouts, we validate payout-based transaction records for you.
2. Serve and Export
In a UI reconciliation report, merchants should be able to click through a resource ID in order to view details about that specific object. In a system which relies on live API calls for data, simply make theGET /resource/id
request when an item is clicked-through. For instance, if a merchant wants to see details of a payment, call GET /payments/id
upon click:curl -X GET \
/payments/9c19298b-319e-49f9-aa38-0de8469e7dc1 \
-H "App-Id: 121212" \
-H "App-Token: prod_MTAwXzk5OWIwZT666LWYwNWItNDU4MS1iZjBiL" \
-H "Api-Version: 3.0" \
-H "Content-Type: application/json" \
For example, a merchant looking through their latest reconciliation report wants to view specific details regarding a payment included in that report. The reconciliation report itself might provide amount information (gross, fees, net, etc), but the merchant wants additional information about that payment. When they click on the resource ID (which in this case is the payment ID) in the UI report, a payment details page loads.
Report on Multiple Merchant Locations
Some merchants, such as franchises, will have multiple locations. Per the guidance on supporting merchants with multiple locations, each location should have its own WePay Account ID, and they should all be tied to the same WePay Legal Entity ID.
Provide custom reporting for these merchants by covering the following use cases:
- Report on each location
- Report on all locations
GET /accounts
request. Send the owner_id
parameter with the Legal Entity ID as the value. The response will be an array of Accounts, and you should parse out the id
parameter for each. Next, decide whether you are generating a transaction history or a reconciliation report.
For transaction history reports, fetch all Transaction Records for each Account ID with aGET /transaction_records
request. Be sure to send the account_id
parameter. For reconciliation reports, fetch all Payouts for each Account ID with a GET /payouts
request with the owner_id
parameter having the Account ID as the value. Next, fetch all Transaction Records associated with each Payout by sending a GET /transaction_records
request with the payout_id
parameter.Platform Reports
As a platform, use our Transaction Records for your own revenue reporting.To find all Transaction Records for Payments, Refunds, Disputes,app_fees
that have impacted your platform WePay balance, send a GET /transaction_records?account_id=YOUR-PLATFORM-ACCOUNT-ID
. Remember that you can find your app Account ID by logging in to partner center. Keep the defaults for create_time_start
and create_time_end
in mind as you construct requests like this.When generating reports for your platform, use these definitions for Transaction Record parameters:
gross_amount
-- The total amount of fees.net_amount
-- The total amount of fees minus WePay fees. For instance, this is the total amount credited to your platform Account balance for a Payment.fee_amount
-- The amount of WePay fees.currency
-- The currency of the associated transaction.type
-- The type of associated resource. For application fee Transaction Records, this value will beapp_fee
.owner
-- A structure defining the associated resource's ID and path.
Platform Revenue
As a platform, you'll want to build out a reporting system to collect data related to your own revenue from WePay transactions. Here, we'll go over the basics on building out that system, which will rely on thetxnr_app_fee.id
parameter of the payments resource.1. Generate
When you receive apayments.created
notification followed by a payments.completed
notification, use the txnr_app_fee.id
value to make a GET /transaction_records/id
request:curl -X GET \
/transaction_records/9c19298b-319e-49f9-aa38-0de8469e7dc1 \
-H "App-Id: 121212" \
-H "App-Token: prod_MTAwXzk5OWIwZT666LWYwNWItNDU4MS1iZjBiL" \
-H "Api-Version: 3.0" \
-H "Content-Type: application/json" \
Data points from the transaction records resource which are vital to platform revenue reporting include:
create_time
gross_amount
- The total amount of fees associated with the originating merchant transactionfee_amount
- The amount of WePay fees contributing to the grossnet_amount
- The total amount of your platform fees contributing to the grossowner.resource
(this will be payments, refunds, disputes, etc.)owner.id
- This will be your platform's account ID
Note that the credit / debit value of the amounts will change depending on the owner resource. For instance, if a transaction record is examining a Payment, the gross and net will be credits to your platform account, and the fee will be a debit from your account and a credit to us.
Store your platform revenue data in a separate data set.
In designing your platform revenue data set, plan for the following columns, as well:
reference_id
from the payments resourcepayment.id
from the refunds and disputes resource
These will need to be retrieved from your general payments data set during parsing, or retrieved live from API responses. This is because those parameters are not present on transaction records resources.
Handling Refunds
If you receive arefunds.created
notification followed by a refunds.completed
notification, store the payload.id
, txnr_app_fee_refund.id
, and payload.payment.id
(which will identify the original impacted payment).Use the txnr_app_fee_refund.id
value to make a GET /transaction_records/id
request:curl -X GET \
/transaction_records/9c19298b-319e-49f9-aa38-0de8469e7dc1 \
-H "App-Id: 121212" \
-H "App-Token: prod_MTAwXzk5OWIwZT666LWYwNWItNDU4MS1iZjBiL" \
-H "Api-Version: 3.0" \
-H "Content-Type: application/json" \
Make a new entry in your platform revenue data set which includes the following:
payload.id
-- from the notificationpayload.create_time
-- from the notification or theGET /transaction_records/id
requestgross_amount
-- fromGET /transaction_records/id
. Indicate that this is a debit since the owner resource is a refundfee_amount
-- fromGET /transaction_records/id
. Indicate that this is a credit from WePay to your app account since the owner resource is a refundnet_amount
-- fromGET /transaction_records/id
. Indicate that this is a debit from your app account to the merchant since the owner resource is a refundpayload.owner.id
-- from the notification or theGET /transaction_records/id
request. This will be your platform's client IDpayload.payment.id
-- from the notification or theGET /refunds/id
request
Handling Disputes
If you receive adisputes.created
notification followed by a disputes.funds_withdrawn
notification, then store the payload.id
, txnr_chargeback_app_fees.id
, and payment.id
. Use the txnr_chargeback_app_fees.id
value to make a GET /transaction_records/id
request:curl -X GET \
/transaction_records/9c19298b-319e-49f9-aa38-0de8469e7dc1 \
-H "App-Id: 121212" \
-H "App-Token: prod_MTAwXzk5OWIwZT666LWYwNWItNDU4MS1iZjBiL" \
-H "Api-Version: 3.0" \
-H "Content-Type: application/json" \
Make a new entry in your platform revenue data set which includes the following:
payload.id
-- from the notificationpayload.create_time
-- from the notification or theGET /transaction_records/id
requestgross_amount
-- fromGET /transaction_records/id
. Indicate that this is a debit since the owner resource is a disputefee_amount
-- fromGET /transaction_records/id
. Indicate that this is a credit from WePay to your app account since the owner resource is a disputenet_amount
--GET /transaction_records/id
. Indicate that this is a debit from your app account to the merchant since the owner resource is a disputepayload.owner.id
-- from the notification or theGET /transaction_records/id
request. This will be your platform's client IDpayload.payment.id
-- from the notification or theGET /disputes/id
request
Note
disputes.resolved
notification and a disputes.funds_reinstated
notification. At this point, use the txnr_chargeback_reversal_app_fee.id
value.2. Serve and Export
You'll want to serve your revenue reports to your internal finance teams. This involves parsing reports from raw data into a .csv file, or any other format needed.
Partner Reports
As a Partner, use our Transaction Summaries and Transaction Metrics for real-time reporting information, similar to what is seen in Partner Center.
Transaction Summaries
Transaction Summaries are a representation of any money movement. These could be merchant-level money movements, but also Partner application-level movements such as withdrawals. It contains various information about an individual transaction including amounts, transaction times, basic fee information, payment method information, etc. The transaction summaries report can also be used to retrieve a list of transactions via various filter options or retrieve a specific transaction by making a request with thetransaction_id
and the transaction_type
for the expected transaction. This endpoint requires one of (
create_time_start
, create_time_end
) or (finish_time_start
, finish_time_end
) to be set. Use the account_id
value to make a GET /transaction_summaries
request: curl -X GET \
/transaction_summaries/ \
-H 'App-Id: <your-app-id>' \
-H 'App-Token: <your-app-token>' \
-H 'Api-Version: 3.2' \
-H 'Content-Type: application/json' \
--data-raw '{
"account_id": "<your-account-id>""
"create_time_start": 1667300000,
"create_time_start": 1667514437
}'
Transaction Metrics
The Transaction Metrics report returns a collection of pre-calculated metrics about transactions.The
GET /transaction_metrics
endpoint requires one of (create_time_start
, create_time_end
) or (finish_time_start
, finish_time_end
) to be set. Use the account_id
value to make a GET /transaction_metrics
request: curl -X GET \
/transaction_metrics/ \
-H 'App-Id: <your-app-id>' \
-H 'App-Token: <your-app-token>' \
-H 'Api-Version: 3.2' \
-H 'Content-Type: application/json' \
--data-raw '{
"account_id": "<your-account-id>""
"create_time_start": 1667300000,
"create_time_start": 1667514437
}'