Connect Sub-Merchants To OptBlue
Now that you've constructed the Legal Entity and Account WePay API objects, you can indicate whether the sub-merchant is enrolled in AmEx's OptBlue program, and whether they would like to receive marketing content about the OptBlue program.
Remember:
The parameters listed here are the required parameters to onboard submerchants as a Payment Facilitator (PayFac). The API reference may indicate different requirements, but those requirements are the default, whereas PayFac requirements are enhanced.
POST /accounts/id
endpoint to update their Account with this information:curl -X POST \
--url 'https://stage-api.wepay.com/accounts/{WePay-Account-ID}' \
-H 'App-Id: {Your-App-Id}'\
-H 'App-Token: {Your-App-Token}'\
-H 'Accept: application/json'\
-H 'Api-Version: 3.0'\
-H 'Content-Type: application/json' \
--data-raw '{
"incoming_payments": {
"amex": {
"program": {
"opt_blue"
},
"countries": {
"US": {
"opt_blue":{
"opt_into_marketing": true
}
}
}
}
}
}'
Two things are achieved by executing the above API call:
- The sub-merchant is indicating that they are an AmEx OptBlue partner simply with the presence of the
opt_blue
object inprogram
- The sub-merchant is indicating that they are open to receiving marketing materials from AmEx when the value for
opt_into_marketing
istrue
(this is enabled astrue
by default)
Here is an example of what the API response may look like:
{
"name": "Example Name",
"description": "Example Description",
"industry": {
"merchant_category_code": "Example MCC",
"category_detail": "Example Category"
},
"reference_id": "Custom reference number",
"statement_description": "Example Statement Description",
"projected_monthly_transaction_volume": null,
"incoming_payments": {
"accepted_methods": ["payment_bank", "visa", "mastercard", "american_express", "discover", "jcb", "diners_club"],
"amex": {
"program": "optblue",
"countries": {
"US": {
"opt_blue": {
"amex_seller_id": "Example Seller ID",
"amex_seller_number": 1234567890,
"opt_into_marketing": false,
}
}
}
}
},
"payout": {
"default_currency": "USD",
"currencies": {
"USD": null
}
},
"custom_data": null,
"create_time": 1234567890,
"balances": {
"currencies": {}
},
"pricing": {
"currencies": {
"USD": {
"credit_card": null,
"payment_bank": null,
"recurring_fee": null,
"other_fees": {
"debit_failure_fee": null
}
}
}
},
"id": "{WePay-generated-UUID}",
"resource": "accounts",
"path": "/accounts/{WePay-generated-UUID}",
"owner": {
"id": "{WePay-generated-Legal-Entity-UUID}",
"resource": "legal_entities",
"path": "/legal_entities/{WePay-generated-Legal-Entity-UUID}"
},
"api_version": "3.0",
"platform_onboarding_time": null,
"beneficiary": {
"id": "{WePay-generated-UUID}",
"resource": "legal_entities",
"path": "/legal_entities/{WePay-generated-UUID}"
},
"documents": []
}
Note that a sub-merchant can only be considered onboarded to AmEx OptBlue when a valid seller ID and number returns.
Handle OptBlue Response Files
In response to AmEx OptBlue onboarding requests, 2 files (Response file & Derog file) will be made available. To access these files, you'll first need to set up access to the SFTP server.
- Work with your integration team at WePay to get your unique public SSH keys (1 for production) from us
- Set up 1 SFTP server on default port 22; 1 for live use in production
- Provide the stage and production SFTP server host name and URLs to your integration team at WePay
- Optional: Generate a GPG key and provide the public key to your integration team at WePay
- Optional: Identify the server directory where you would like us to send response files. If none is identified, all files will be placed in the root directory
Onboarding Response File
The onboarding response file will contain any failures to onboard merchants to AmEx OptBlue for the previous day. This file will be uploaded within 48 hours.
The file will contain various merchant identifiers, including the seller ID and the WePay Account ID. There are two possible reasons that a merchant would be included in this file:1. The merchant has been rejected by AmEx
In these cases, a reason will be present in the Data_Reject_Code_By_Amex column of the file indicating the field causing the rejection. Update the appropriate field in either a
POST /accounts/id
or a POST /legal_entities/id
request.Data_Reject_Code_By_Amex | Description |
---|---|
SD | Invalid name on Account |
SM | Invalid industry.merchant_category_code on Account |
SS | Invalid address.line1 on Legal Entity |
SN | Invalid address.city on Legal Entity |
SR | Invalid address.region on Legal Entity |
SP | Invalid address.postal_code on Legal Entity |
SC | Invalid address.country on Legal Entity |
SU | Invalid currency, derived from address.country on Legal Entity |
AX | Please contact us for details |
Use the following table to map column names to API fields, and fix the data in either a
POST /accounts/id
or a POST /legal_entities/id
request.Onboarding Failure File Column Name | API resource & field |
---|---|
Entity details | |
Accounts_Name | /accounts name |
Accounts_Merchant_Category_Code | /accounts industry.merchant_category_code |
Accounts_Opt Blue_Opt into marketing | /accounts incoming_payments.amex.countries.US.opt_blue.opt_into_marketing |
Legal Entities_Entity_name | /legal_entities entity_name |
Legal Entities_Employee_identification_number | /legal_entities entity_country_info.US.employer_identification_number |
Legal Entities_Entity_Address_Line1 | /legal_entities address.line1 |
Legal Entities_Entity_Address_Line2 | legal_entities address.line2 |
Legal Entities_Entity_Address_City | /legal_entities address.city |
Legal Entities_Entity_Address_Region | /legal_entities address.region |
Legal Entities_Entity_Address_Postal_code | /legal_entities address.postal_code |
Legal Entities_Entity_Address_Country_code Note: This field indicates that there is an issue with the account's currency, which is derived from the Legal Entity's country code | /legal_entities address.country |
Legal Entities_Entity_Address_Phone_number | /legal_entities phone.* |
Legal Entities_Entity_Controller_Primary_url | /legal_entities primary_url |
Legal Entities_Entity_Address_country_code | /legal_entities address.country |
Legal Entities_Entity_Controller_Legal_form | /legal_entities entity_country_info.US.legal_form |
Legal Entities_Controller_enterprise_customer_id | /legal_entities enterprise_customer_id |
Controller details | |
Legal Entities_Entity_Controller_Email | /legal_entities controller.email |
Legal Entity_Controller_Firstname | /legal_entities controller.name.first |
Legal Entity_Controller_Lastname | /legal_entities controller.name.last |
Legal Entities_Controller_Date of birth | /legal_entities controller.date_of_birth.* |
Legal Entities_Controller_Address_Line1 | /legal_entities controller.address.line1 |
Legal Entities_Controller_Address_Line2 | /legal_entities controller.address.line2 |
Legal Entities_Controller_Address_City | /legal_entities controller.address.city |
Legal Entities_Controller_Address_Region | /legal_entities controller.address.region |
Legal Entities_Controller_Postal code | /legal_entities controller.address.postal_code |
Legal Entities_Controller_Country code | /legal_entities controller.address.country |
Additional Representative Details | |
Legal Entities_Additional representative1_First_name | /legal_entities additional_representatives.representative_0.name.first |
Legal Entities_Additional representative1_Last_name | /legal_entities additional_representatives.representative_0.name.last |
Legal Entities_Additional representative1_Social_security_number | /legal_entities additional_representatives.representative_0.personal_country_info.US.social_security_number |
Legal Entities_Additional representative1_Date_of_birth | /legal_entities additional_representatives.representative_0.date_of_birth |
Legal Entities_Additional representative1_Address_Line1 | /legal_entities additional_representatives.representative_0.address.line1 |
Legal Entities_Additional representative1_Address_Line2 | /legal_entities additional_representatives.representative_0.address.line2 |
Legal Entities_Additional representative1_Address_City | /legal_entities additional_representatives.representative_0.address.city |
Legal Entities_Additional representative1_Address_Region | /legal_entities additional_representatives.representative_0.address.region |
Legal Entities_Additional representative1_Address_Postal_code | /legal_entities additional_representatives.representative_0.address.postal_code |
Legal Entities_Additional representative1_Address_Country_code | /legal_entities additional_representatives.representative_0.address.country |
Legal Entities_Additional representative1_Address_Country_code | /legal_entities additional_representatives.representative_0.address.country |
Legal Entities_Additional representative2_First name | /legal_entities additional_representatives.representative_1.name.first |
Legal Entities_Additional representative2_Last name | /legal_entities additional_representatives.representative_1.name.last |
Legal Entities_Additional representative2_RepresentativeId | /legal_entities additional_representatives.representative_1.reference_id |
Legal Entities_Additional representative2_Date of birth | /legal_entities additional_representatives.representative_1.date_of_birth.* |
Legal Entities_Additional representative2_Address_Line1 | /legal_entities additional_representatives.representative_1.address.line1 |
Legal Entities_Additional representative2_Address_Line2 | /legal_entities additional_representatives.representative_1.address.line2 |
Legal Entities_Additional representative2_Address_City | /legal_entities additional_representatives.representative_1.address.city |
Legal Entities_Additional representative2_Address_Region | /legal_entities additional_representatives.representative_1.address.region |
Legal Entities_Additional representative2_Address_Postal code | /legal_entities additional_representatives.representative_1.address.postal_code |
Legal Entities_Additional representative2_Address_Country code | /legal_entities additional_representatives.representative_1.address.country |
Legal Entities_Additional representative3_First name | /legal_entities additional_representatives.representative_2.name.first |
Legal Entities_Additional representative3_Last name | /legal_entities additional_representatives.representative_2.name.last |
Legal Entities_Additional representative3_RepresentativeId | /legal_entities additional_representatives.representative_2.reference_id |
Legal Entities_Additional representative3_Date of birth | /legal_entities additional_representatives.representative_2.date_of_birth.* |
Legal Entities_Additional representative3_Address_Line1 | /legal_entities additional_representatives.representative_2.address.line1 |
Legal Entities_Additional representative3_Address_Line2 | /legal_entities additional_representatives.representative_2.address.line2 |
Legal Entities_Additional representative3_Address_City | /legal_entities additional_representatives.representative_2.address.city |
Legal Entities_Additional representative3_Address_Region | /legal_entities additional_representatives.representative_2.address.region |
Legal Entities_Additional representative3_Address_Postal code | /legal_entities additional_representatives.representative_2.address.postal_code |
Legal Entities_Additional representative3_Address_Country code | /legal_entities additional_representatives.representative_2.address.country |
Legal Entities_Additional representative4_First name | /legal_entities additional_representatives.representative_3.name.first |
Legal Entities_Additional representative4_Last name | /legal_entities additional_representatives.representative_3.name.last |
Legal Entities_Additional representative4_RepresentativeId | /legal_entities additional_representatives.representative_3.reference_id |
Legal Entities_Additional representative4_Date of birth | /legal_entities additional_representatives.representative_3.date_of_birth.* |
Legal Entities_Additional representative4_Address_Line1 | /legal_entities additional_representatives.representative_3.address.line1 |
Legal Entities_Additional representative4_Address_Line2 | /legal_entities additional_representatives.representative_3.address.line2 |
Legal Entities_Additional representative4_Address_City | /legal_entities additional_representatives.representative_3.address.city |
Legal Entities_Additional representative4_Address_Region | /legal_entities additional_representatives.representative_3.address.region |
Legal Entities_Additional representative4_Address_Postal code | /legal_entities additional_representatives.representative_3.address.postal_code |
Legal Entities_Additional representative4_Address_Country code | /legal_entities additional_representatives.representative_3.address.country |
Use Seller IDs and Numbers
The API response will contain theamex_seller_number
and amex_seller_id
parameters. Use those values when executing OptBlue transactions via Chase Merchant Services for that sub-merchant. If the sub-merchant's preference for receiving marketing materials from AmEx ever changes, send another
POST /accounts/id
request for the appropriate sub-merchant with the new value for opt_into_marketing
.If the sub-merchant ever offboards from the OptBlue program, you must send another
POST /accounts/id
request for the appropriate sub-merchant with none
as the value for program
. The API request to update the WePay Account must be sent when the sub-merchant offboards from OptBlue.Any subsequent requests making an update to any field in the WePay Account will result in an API Notification being sent to the
accounts.updated
event topic.Offboard Sub-Merchants
If a sub-merchant ever offboards from the OptBlue program, you must send anotherPOST /accounts/id
request for the appropriate sub-merchant with none
as the value for program
instead of an object. The API request to update the WePay Account must be sent when the sub-merchant offboards from OptBlue.This offboarding flow should be used for American Express blacklisted sub-merchants (identified in the Derog file) and for normal offboarding processes.
Below is an example request to offboard a sub-merchant from the OptBlue program:
curl -X POST \
--url 'https://stage-api.wepay.com/accounts/{WePay-Account-ID}' \
-H 'App-Id: {Your-App-Id}'\
-H 'App-Token: {Your-App-Token}'\
-H 'Accept: application/json'\
-H 'Api-Version: 3.0'\
-H 'Content-Type: application/json' \
--data-raw '{
"incoming_payments": {
"amex": {
"program": {
"none"
}
}
}
}'
Next to Handle MATCH Results