Overview
Introduction
API Host
https://api.q2open.io/v1 (production)
https://sb-api.q2open.io/v1 (sandbox)
Resource URL Patterns
/auth
/bill
/company
/payment
/client
Welcome! The Q2 Biller Direct API allows developers to receive user-authorized bill data and make payments on behalf of a user.
Here you will find information on how to integrate with and use the Q2 Biller Direct API. We've tried to make this documentation user-friendly and example-filled, but please drop us a line with any questions.
The Q2 Biller Direct API uses standard HTTP verbs to communicate and HTTP response codes to indicate status and errors. All responses come in standard JSON. The Q2 Biller Direct API is served over HTTPS to ensure data privacy, HTTP is not supported.
Testing
To quickly experiment with the API, you can use Postman. You'll need to set the apiHost
and apiKey
environment variables.
Testing with Dedicated Test Companies
Always use these dedicated test companies when developing on Sandbox. By using the below listed test companies and the input fields, it is possible to get a auth, bill, or swap into most statuses the end user may encounter. If you are unable to see these companies when searching on Sandbox, please reach out to your Q2 point of contact.
Input | Description |
---|---|
balance |
The desired balance |
dueDate |
The desired due date in mm/dd/yyyy format |
status |
The desired auth/bill/swap status |
Company Name | Description |
---|---|
Regular Company 1 thru 5 | A standard company to test against |
MFA Company 1 thru 2 | A company that requires Code or Prompt Based MFA in order to authenticate |
Legacy Test Company
This testing path will still work, but the new test companies above are the new standard when developing on Sandbox.
You may perform a test authentication with any company to test various use cases. Each use case is triggered based on the username
or email
used to authenticate. Any password may be used. Here's a list of credentials and their associated test case:
Test Credentials
Input | Description |
---|---|
test |
Test a successful authentication. |
testfail |
Test an authentication failure. |
testhold |
Test an authentication hold. |
testmfaquestion |
Test an authentication requiring question-based MFA. |
testmfacode |
Test an authentication requiring code-based MFA. |
testmfaprompt |
Test an authentication requiring prompt-based MFA. |
testpaymentfail |
Test a payment failure. |
testswap |
Test performing a post-authentication swap. Useful when using Connect with a paymentMethodId . |
When a company requires an email
as input, append @test.test.
to any of the test credentials above. For example, to test an authentication failure, use testfail@test.test
.
You may test a successful payment within the Sandbox environment by using 4111111111111111
as the card number, with any valid expiration, zipcode, and random 3-digit CVV.
Legacy Test Company Limitations
- You cannot make payments on Sandbox.
- When using your real account, there may be cases where it will accept invalid credentials or not retrieve your bill data. If you'd like to do a real test with these providers, you'll need to use our production environment.
Gaining Access
To gain access to the Q2 Biller Direct API, please contact us. After our review process is complete, you'll be provided with an API key which you can use for your requests.
Authentication
Authenticate your account when using the API by including your secret API key in the request. Your API keys carry many privileges, so be sure to keep them secret! Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, and so forth.
Authentication to the API is performed via bearer tokens. Pass your API Key as a bearer token in the Authorization
header.
Example Request
curl "https://api.q2open.io/v1/bill/list/579b695decfa11012711875d"
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e"
Errors
Q2 Biller Direct API uses HTTP response status codes to indicate the success or failure of your API requests. If your request fails, Q2 Biller Direct API returns an error using the appropriate status code.
In general, there are three status code ranges you can expect:
2xx
success status codes confirm that your request worked as expected4xx
error status codes indicate an error because of the information provided (e.g., a required parameter was omitted)5xx
error status codes are rare and indicate an error with Q2 Biller Direct API's servers
Request IDs
Each API request has an associated request identifier. You can find this value in the response headers, under request-id
. If you need to contact us about a specific request, providing the request identifier will ensure the fastest possible resolution.
Getting Started
Our white-label products are the fastest way to implement our API's functionality with a design that fits your branding. If you require a more custom integration you may use the following flow.
User Creation
- User signs up in your app.
- Make a request to the
/client
endpoint to retrieve aclientId
to store in your database for future requests.
Authentication
- Make a request to the
/client/create-token
endpoint to retrieve a secure SSO token to link accounts. - Link accounts by integrating the Connect product into your application.
Bills
- Requests can be made to the
/bill/list/{clientId}
endpoint to retrieve the list of authenticated bills and balance information. - Requests can be made to the
/bill/{billId}
endpoint to retrieve details on a specific bill.
Payments
- Provide your user with a "link payment" view to choose a payment method.
- Link this payment method using the
/payment
endpoint. - By default, bills will be paid automatically by using the payment method on file.
- To change this, you must make a request to the
/payment/settings
endpoint to disable recurring payments. - When recurring payments are disabled, in order to make an on-demand payment, one must be scheduled via the
/payment/schedule
endpoint. - You can cancel a scheduled payment for a bill by using the
/payment/cancel
endpoint.
Message Security
RSA/AES Encryption
Example Encrypted Request
{
"encrypted": "os8th269xgj7tyku7wxl",
"hash": "PQ5+gSzli4DyOzXUYqT74QIZ9l4VIyWJipb521HfUnwwj0sNPp0ASyodxb3YOmhbM6nZ+bFXkPN1u2vcXo80yYcMy0xXmfcQ27LRsVjD8kLw7PC0LSfKh1ZHvx+xpxnHDDOYwqRMVFUHIz6ggxPJB39f7hZXRvp5JQQhnB/3JfpV/UvmXjhdQlgC50yOOIJ12S36cnncBrwqYvvDV7iY8Uq6x2ddZRl/2GNoUpnf9jIoKEqeNEpuqoD9g6cwcXXgbjyObxfl6zOSQlfgHJye/Me7E0d+4r0/OWhnSYC6GgedAwUM1fBVGAkAqQKEtU2BYD1kIP8hBSMJxWzVjqKn0A=="
}
Optionally, message encryption may be used when making a POST
request to the API.
- Message encryption uses a combination of AES and RSA encryption.
- The message payload is encrypted using AES-CTR-256.
- The resultant AES key is then encrypted using an RSA 2048-bit public key.
- RSA key-pairs can be created in the Nexus portal
Settings
view, and the public key can be copied.- A maximum of 2 keys can be created for key rotation purposes.
- Public keys are copied in PCKS #8 format.
- Public keys can also be retrieved from the partner public key API.
- The examples GitHub repository includes an example of encrypting the payload with your public key using a combination of AES and RSA encryption.
- Use the API routes as documented, however your payload will be encrypted and base64 encoded using the public key, and sent in a
hash
parameter. - Add an
encrypted
parameter to your request with the key identifier that is created when you generate an RSA key in Nexus.
RSA Request Signing
Example Signed Request
curl "https://api.q2open.io/v1/client/create-token" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Signature: MzfMtn6M9rpHyzGSvBPkzbNZlne+rf3tkcLUeMUW8mOMmdP1VtnnVdQA9hdYVObjwibOGdRQmCeoI9Xba5DXGT2/l9wOSJQ4FI90DssY1l+orOiwVwY8quAgBUYd2YDDUGyEJ31Y9yOgwLBp2xC4pA5vfkYtWAC9PccdxDyMZcCm6pz3AVgfCRN1m2rcZsE/VrhWhZof3sYitP3zTfV7KCF3T232HPHQtEYtEMLE4Pi7t4i+KvR4Rejt4a7DIgba3OfVmWf5La7WzdlU4eneIPnVjk3CGUo4t9PIPJQVbLyDSIXiF9pRD8ZlW+19XUe/HyWFHR4em00nbaNjBG4TSQ==" \
-H "Date: 2019-09-17T14:14:24.874Z" \
-H "Content-Type: application/json" \
-d '{
"identifier": "5b2bd638bdf6035960b98694"
}'
-X POST
Optionally, 2048-bit asymmetric request signing may be used when making requests to the API.
Keypair Provisioning
API request signing key-pairs can be added manually in the Nexus portal or in automated fashion by providing an API endpoint.
Manual
- Create a 2048-bit RSA keypair following the PKCS #1/sha-256 signing scheme.
- Update the API Request Signing Public Key in the Q2 Nexus portal
Settings
view.
Partner Provided API
An API endpoint may be provided by the partner which the Biller Direct/Cardswap system will use to keep signing keys synchronized. Keys will be requested from the API daily. It is assumed that the expiration of a new partner RSA signing key will be several days at a minimum. If no valid keys are present, the BDCS retrieval job will ping the partner endpoint several times daily to request valid keys. The API must return keys in standard JWKS (JSON Web Key Set) format. Please refer to the JWK standards for more information.
When setting up the API endpoint in Nexus, a collection of headers can also be added if the endpoint requires additional metadata to function. Headers are provided in JSON format.
Signing the API Request
- With each request to the API, generate a signature using the following formula:
- Request method in all uppercase:
POST/PUT/GET/DELETE
plus a colon. - Path and query of the request plus a colon.
- Your API Key plus a colon.
- The current date and time in ISO format
- Example:
POST:/v1/client/create-token:YOUR_API_KEY:2019-09-17T14:14:24.874Z
- Request method in all uppercase:
- Use an RSA signing library to create an RSA signature from the signature text with the pkcs1-sha256 signing scheme.
- Encode the produced signature as a Base64 string.
- Add the Base64 signature in the
Signature
header of the request. - Add the date that was included in the signature to the
Date
header of the request.
When request signing is enabled, a signature must be provided with every API request.
If the signature is not provided, a 401-Unauthorized
response will result.
Products
Our white-label products are the fastest way to implement our API's functionality with a design that fits your branding. We've built a set of products that key in on common use cases of our API. These products include Connect, CardSwap and Biller Direct.
WebView Integration
Integration with our products is straightforward.
- Create a one-time use token by making a call to the
/client/create-token
endpoint. - SSO into the white-label product by passing in the token as a URL parameter. An example URL would look like this:
https://product.q2open.io?token=123
.
Example Code
See our iOS and Android integration examples for example implementations in Swift and Java.
Connect
Host
https://connect.q2open.io (production)
https://sb-connect.q2open.io (sandbox)
Connect is a drop-in module that provides a secure, elegant authentication flow for each company that the Q2 Biller Direct API supports. Connect makes it secure and easy for clients to link their accounts, while doing the heavy lifting for the authentication.
Connect Events
Connect will emit events back to your app using the browser postMessage API, WKScriptMessageHandler on iOS, or addJavascriptInterface on Android, allowing you to decide what to do after the user is finished.
Event | Description |
---|---|
auth |
The user successfully authenticated with a company. |
exit |
The user exited the module without completing an authentication. |
alive |
Emitted every 30 seconds to indicate that the user is not idle. |
userPresenceRequired
If the company requires that the user is present to pass through any security flows with every login,
as indicated by the company.userPresenceRequired
flag, there are a number of constraints to consider when designing your user experience:
- Bill data cannot be updated ad-hoc without the user first passing through security.
- Payments must be completed in real-time (not scheduled) since the user must be present.
- Likewise, Swaps must also be completed in real-time with the user present.
Instead of calling the typical API routes, you'll need to open Connect to perform these actions immediately after a successful authentication. The user won't need
to re-enter their username and password, but may need to step through security. Using the authId
, billId
, items
, and paymentMethodId
URL parameters as
documented below, you'll be able to make payments and swaps in real-time, while allowing users the liberty of maintaining their approach to account security.
URL parameters
The following URL parameters can be optionally passed into the Connect URL to customize the experience.
Parameter | Description |
---|---|
companyId |
Deeplink to a specific companyId , skipping the search screen. |
swapId |
Can be used in conjunction with paymentMethodId to move a swap to a different payment method. |
billId |
Can be used in conjunction with paymentMethodId to make a payment when company.userPresenceRequired is true . |
cardPaymentsOnly |
Limit searches to companies that support card-based payments. |
items |
Indicates the next desired action once an authentication is successful. Set to swap to automatically create a Swap. Set to bill to update bill data. Set to payment (in conjuction with a billId) to make a real-time payment towards the balance. |
paymentMethodId |
Sets a previously added payment method to be used for a swap or payment once an authentication is successful. |
URL Examples
To authenticate with a company:
https://connect.q2open.io?token=123&companyId=123&items=bill
To make a payment when company.userPresenceRequired
is true
:
https://connect.q2open.io?token=123&billId=123&paymentMethodId=123&items=payment
To initiate a new swap:
https://connect.q2open.io?token=123&companyId=123&paymentMethodId=123&items=swap
To move a swap to a different payment method:
https://connect.q2open.io?token=123&swapId=123&paymentMethodId=123&items=swap
To assign the paymentMethodId as the preferred payment method on a bill:
https://connect.q2open.io?token=123&companyId=123&paymentMethodId=123&items=bill
CardSwap
Host
https://cardswap.q2open.io (production)
https://sb-cardswap.q2open.io (sandbox)
Q2 CardSwap™ is the first switch kit for subscription and eCommerce merchants, allowing users to put your card top-of-wallet for their favorite services—all in one place.
CardSwap Events
CardSwap will emit events back to your app using the browser postMessage API, WKScriptMessageHandler on iOS, or addJavascriptInterface on Android, allowing you to decide what to do after the user is finished.
Event | Description |
---|---|
finish |
Occurs when the user successfully completes the swap process. Only emits when the startView URL parameter is set to brands . |
URL parameters
The following URL parameters can be optionally passed into the CardSwap URL to customize the experience.
Parameter | Description |
---|---|
startView |
Indicates where users are redirected to after completing a swap. Set to brands to skip the introductory page and return users to the brand selection page. |
sessionId |
Session ID to be linked to corresponding Events. |
Biller Direct
Host
https://biller-direct.q2open.io (production)
https://sb-biller-direct.q2open.io (sandbox)
Biller Direct is a card-enabled bill pay solution designed to dramatically improve the user experience and economic model of bill pay.
Biller Direct Events
Biller Direct will emit events back to your app using the postMessage API or WKScriptMessageHandler on iOS, allowing you to decide what to do after the user is finished.
Event | Description |
---|---|
alive |
Emitted every 30 seconds to indicate that the user is not idle. |
URL parameters
The following URL parameters can be optionally passed into the Biller Direct URL to customize the experience.
Parameter | Description |
---|---|
companyId |
Deeplink to a specific bill for the companyId specified if a bill already exists, or fallback to the authentication screen for the specified companyId . |
billId |
Setting to a specific Bill _id will deeplink the user into the detailed view of the bill. |
skipOnboarding |
Setting to true will skip the introductory screens and animations. |
cardPaymentsOnly |
Limit searches to companies that support card-based payments. |
Sessions
Example Event with
sessionId
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "session.example",
"created": "2016-04-20T16:51:12Z",
"sessionId": "yoursessionid"
"payload": {
"resource": {
"type": "example",
"id": "579b695decfa11012711875d"
},
"data": {
"example": "session"
}
}
}
}
Adding a sessionId
as a URL parameter will link that sessionId
to any Events that happen during your customer's session. We recommend creating a new sessionId
every time a customer uses a white-label product.
URL Example
https://cardswap.q2open.io?token=123&sessionId=yoursessionid
Auth
Authenticating client accounts can be implemented using the Connect product.
Create auth
Example Request
curl "https://api.q2open.io/v1/auth" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"items": ["bill"],
"paymentIdentifier": "PaymentIdentifier001",
"meta": {
"paymentMethodId": "56e1ddbd1a05319bc198d36f",
"billId": "579b695decea110719b1874d"
},
"clientId": "579b695decfa11012711875d",
"companyId": "579b695decea110719b1874d",
"form": {
"email": "example@example.com",
"password": "12345678"
}
}'
Example Response
{
"success": true,
"message": "Auth has been queued and will respond via webhooks.",
"authId": "579b695decea110719b1874d"
}
Instead of using the Connect Product to handle collecting and verifying credentials, the auth endpoint can be used in conjunction with webhook events and the auth step endpoint to have full control of the user experience. Due to the complexity of the auth process, the webhook events that support this are not enabled by default. Please reach out to your customer support contact to discuss using this feature.
Create auth submits a request to validate given credentials then retrieves bill data, initiates a payment, or performs a swap. Initiating a payment through the auth endpoint is only necessary when userPresenceRequired
is true. When userPresenceRequired
is true, this means the client is setup on the company's site to use code or prompt based MFA.
HTTP Request
POST https://api.q2open.io/v1/auth
Arguments
Parameter | Description |
---|---|
clientId |
ID of client to create the auth for. |
companyId |
ID of the company to validate credentials for. |
items |
What to do after validating credentials. Valid items are bill , payment , and swap . swap should not be used with the others. |
paymentIdentifier |
Optional custom identifier for external system correlation. |
meta.paymentMethodId |
Optional ID of payment method to assign. |
meta.billId |
Optional ID of existing bill. Should not be used with swapId. |
meta.swapId |
Optional ID of existing swap. Should not be used with billId. |
form |
Required login fields that are unique to each company. Usually email/username and password, but sometimes it can be more such as phone number or account number |
Returns
A success message and the new or existing authId for the given company.
Auth Step
Example Request
curl "https://api.q2open.io/v1/auth" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"token": "6218f231494a186f08983d89",
"method": "code",
"security": {
"identifier": "P4erF9C__n73GY",
"answer": "44555"
}
}'
Example Response
{
"success": "true",
"message": "Auth security response has been queued and will respond via webhooks."
}
When create auth requires additional security, the system will send out a webhook asking for answers to questions based, code based, or prompt based style security.
Use the auth step endpoint to respond to security webhook events to progress through the realtime credential validation process.
HTTP Request
POST https://api.q2open.io/v1/auth/step
Arguments
Parameter | Description |
---|---|
token |
ID provided by webhooks for correlation to the auth validation process. |
method |
String of the type of response this correlates to: 'questions', 'code', 'prompt' |
security |
Object containing the response to the webhook request for security information. |
didNotReceiveCode |
Boolean used if the user never received the code that was requested. |
Example Auth Webhooks and Steps
Questions Based MFA
Questions Based MFA example Webhook
{
"resource": {
"id": "6217deda4c94a9f552489392",
"type": "client"
},
"data": {
"auth": {...},
"method": "questions",
"input": [
{
"identifier": "ibY1g2PC4wrc6q",
"question": "What is your mother's maiden name?"
},
{
"identifier": "P4erF9C__n73GY",
"question": "What is your favorite color?"
}
],
"token": "6218f985494a186f08983ec2"
}
}
Auth Step for Questions Based MFA
{
"token": "6218f985494a186f08983ec2",
"method": "questions",
"security": [
{
"identifier": "ibY1g2PC4wrc6q",
"answer": "Smith"
},
{
"identifier": "P4erF9C__n73GY",
"answer": "White"
},
]
}
Security questions that are required to verify user. If these are not answered by the client in realtime, they can be answered with Answer Questions
Code Based MFA
Code Based MFA example Webhook
{
"resource" : {
"type" : "client",
"id" : "5d9b819aacffca301b076958"
},
"data" : {
"company" : {...},
"method" : "code",
"input" : [
{
"type" : "text",
"mask" : "xxx-xxx-1234",
"identifier" : "Xf9DWrxK_",
"label" : "Text: xxx-xxx-1234"
},
{
"type" : "email",
"mask" : "e..e@example.com",
"identifier" : "fWaGHa00al",
"label" : "Email: e..e@example.com"
}
],
"token" : "5d9ca25aa71f7c94d0fad1b1"
}
}
Auth Step for Code Based MFA
{
"token": "5d9ca25aa71f7c94d0fad1b1",
"method": "code",
"security": {
"identifier": "Xf9DWrxK_"
}
}
Follow up question for Code Bade MFA
{
"resource": {
"id": "6217deda4c94a9f552489392",
"type": "client"
},
"data": {
"auth": {...},
"method": "questions",
"input": [
{
"identifier": "QMbuXxBKqnDvYC",
"question": "What is the code sent to xxx-xxx-1234?"
}
],
"showRetry": true,
"token": "6218f985494a186f08983ec2"
}
}
Security that asks where the client wants the code sent to. Typically either email, phone number, or a device. This will then be followed up with a webhook asking what is the code that was sent. The field showRetry
true means the client can use the didNotReceiveCode
for the auth step to try to get another code sent. It should be designed to wait at least 30 seconds before allowing the client to send the try again request.
Prompt Based MFA
Prompt Based MFA example Webhook
{
"resource": {
"id": "6217deda4c94a9f552489392",
"type": "client"
},
"data": {
"auth": {...},
"method": "prompt",
"input": [
"request": "Verify your login with your mobile device"
],
"token": "6218f231494a186f08983d89"
}
}
Auth Step for Prompt Based MFA
{
"token": "6218f231494a186f08983d89",
"method": "prompt"
}
Security measure that requires the user to click a prompt sent to a device or email. The response does not need a security payload as this is just an acknowledgement that the prompt was pressed.
The auth object
Example Response
{
"_id": "579b695decea110719b1874d",
"status": {
"type": "verified"
},
"company": {
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
}
}
}
Attribute | Description |
---|---|
_id |
ID of the auth. |
status |
Status of the auth. |
company |
Company Object |
Auth status
Verified Response
{
"status": {
"type": "verified"
}
}
Authenticate Response
{
"status": {
"type": "authenticate"
}
}
Hold Response
{
"status": {
"type": "hold"
},
"reason": {
"userMessage": "You need to login and verify your account information.",
"code": "account_issue_verify_identity"
}
}
MFA Required Response
{
"status": {
"type": "mfa-required"
},
"mfa": {
"method": "questions",
"mfa": [{
"question": "What city did you grow up in?",
"identifier": "1j5k2l1"
},
{
"question": "What is your favorite food?",
"identifier": "3buw78h3"
}]
}
}
An auth status.type
can be a variety of types. Each type is documented below with a description of the status and a typical use case.
verified
The user's auth has been verified. No actions are required.
For Testing this will happen as long as no other valid auth status is entered.
authenticate
The auth's credentials are no longer valid and need to be reauthenticated using the Connect product.
For Testing set status
to authenticate
. balance
and dueDate
are ignored.
hold
An auth's status can be hold
for several reasons. When an auth is on hold, the response contains a reason
for the hold that you can present to your users. To fix the hold, the user must perform the action described in the reason
, which usually requires them to log in to their online account. Once the user has completed the action, make a request to the /auth/{authId}/fix-hold
endpoint to resume their services.
Additionally, a code is provided for handling the hold programmatically, if required.
Display hold reason
Displayed after user returns to app
For Testing set status
to hold
. The account_issue_accept_toc
hold code will be placed on the auth. balance
and dueDate
are ignored.
MFA Required
When the link with a company requires additional MFA.
For Testing set status
to mfa-required-questions
. balance
and dueDate
are used for bills but ignored for swaps. Additionally to test code and prompt based MFA that requires user to be present, use mfa-required-code
and mfa-required-prompt
in the status
field.
Auth hold codes
Auth hold's include a code - a short string with a brief explanation - as a value for code
. Below is a list of possible codes that can be returned, along with our default messaging and the products they relate to.
account_issue_apple_pay_on_file
Your payment method could not be updated because your iTunes payments are made via Apple Pay. Please update your payment method directly through Apple Pay.
account_issue_disney_plus_third_party_on_file
Your Disney+ subscription is currently being paid by a third party provider such as iTunes, Verizon, or the Disney bundle. Sign in to your Disney+ account if you want to change the payment method to your card.
account_issue_payment_details_required
This provider requires additional information. Contact them directly to update your payment method.
account_issue_with_swap
We couldn't update your payment method because of an issue with your account. Please go to the provider directly to update your payment method.
account_issue_primary_account_holder
We can't update your payment method because you aren't the primary account holder for this provider. Please provide the username and password of the main account holder.
account_issue_card_not_accepted
We can't update your payment method because this card isn't accepted by the provider. Contact the provider directly to resolve this issue, then try again.
account_issue_max_cards_on_file
We can't update your payment method because the provider won't allow any more cards to be added. Please sign in directly on the provider's website to remove a payment method and try again.
account_issue_third_party_connected
We couldn't update your payment method because you're paying for your subscription through a third-party provider (like PayPal or Google Play). Please go to the third-party provider directly to update your payment method.
account_issue_third_party_available
We couldn't update your payment method because you're paying for your subscription through a third party, such as iTunes or Amazon. To change your payment method, select the third party from the list of providers to add your card.
account_issue_no_active_subscription
We couldn't add your card because you don't have an active subscription with this provider. Please activate your subscription and try again.
system_issue_with_swap
We couldn't update your payment method because of a technical problem. Please try again.
provider_system_issue
We’re unable to complete the swap because of a system issue with the provider. Please try again later.
partner_expiration_exceeded
This request has exceeded your financial institution's expiration policy.
account_issue_account_locked
Your account has been locked. Unlock your account directly through your provider and try again.
authentication_unsupported
We’re unable to access your account because your login credentials are from a third-party service, such as Facebook or Google. To link your account, disconnect from the third-party service and create new login credentials directly through the provider.
authentication_not_completed
We're unable to access your account because authentication was not fully completed. Please re-authenticate your login credentials and try again.
account_set_up_online_payments
Your account is not set up for online payments. Log in to your account and set up online payments.
account_issue_verify_identity
Please log in to your account to set up and verify your personal information.
account_issue_accept_toc
Please log in to your account and accept the Terms and Conditions.
account_issue_no_service_account
Please log in to your account and add a service account.
account_issue_third_party_payments_on_file
We're unable to access your bill information because your account is connected to a third-party provider.
system_issue_with_bill
We're unable to access your bill information because of a system issue. Please try again later.
system_issue_with_bill_payment
We're unable to submit this payment because of a system issue. Please try again later.
account_paid_in_full
We’re unable to locate a balance on your account because it is paid in full.
account_issue_payment_restrictions
We're unable to submit payments due to restrictions on your account.
account_issue_inactive_account
We're unable to make payments on inactive accounts.
account_issue_no_bill
We are unable to locate a bill on this account. Please contact your provider directly
no_payment_required
There are currently no payments required for this bill because it is in forbearance or your account has been inactive for 6 months or longer.
foreign_currency_issue
We are unable to update or pay your bill due to foreign currency exchange. Please contact your provider directly.
Subcategories for authentication_not_completed
Code | Description |
---|---|
invalid-credentials |
The credentials provided are invalid. |
no-mfa-response-received |
The user did not provide a MFA response during a realtime job. |
invalid-mfa |
The MFA response provided by the user was invalid. |
unanswered-mfa-question |
There are MFA questions during the authentication process that the user had not provided answers for. |
Subcategories for system_issue_with_swap
, system_issue_with_bill_payment
and system_issue_with_bill
Code | Description |
---|---|
selector-not-found |
Automation was not able to detect expected selector. |
navigation-error |
Automation job encountered navigation error. |
job-timeout |
Automation job timed out. |
captcha-failure |
Automation failed to solve the captcha on the provider website. |
proxy-failure |
Automation job encountered proxy failure. |
known-system-error |
Automation job encountered known system error. |
issue-unidentified |
Automation job failed due to unidentifiable issues. |
List all auths
Example Request
curl "https://api.q2open.io/v1/auth/list/566595c8ce88ccec69328566" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-G
Example Response
{
"data": [
{
"_id": "579b695decfa11012711875d",
"status": {
"type": "verified"
},
"company": {
"_id": "579b695decea110719b1874d",
"name": "Time Warner Cable",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/4c805851c738c006546b234e3c3c793d.png",
"background": false
}
}
},
{
"_id": "579b695decfa11012711875d",
"status": {
"type": "authenticate"
},
"company": {
"_id": "579b695decea110719b1874d",
"name": "The Grove at Auburn",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/0e9a971a96646da46f5faa68862d0f2d.jpg",
"background": true
}
}
}
]
}
Retrieves a list of client's auths.
HTTP Request
GET https://api.q2open.io/v1/auth/list/{clientId}
Arguments
Parameter | Description |
---|---|
clientId |
ID of client to retrieve auths for. |
Returns
A dictionary with a data
property that contains an array of auth objects.
Fix auth hold
Example Request
curl "https://api.q2open.io/v1/auth/566595c8ce88ccec69328566/fix-hold" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-X POST
Example Response
{
"success": true
}
HTTP Request
POST https://api.q2open.io/v1/auth/{authId}/fix-hold
Arguments
Parameter | Description |
---|---|
authId |
ID of auth to fix. |
Returns
Returns an object with a success
property if the hold was fixed. If the authId
does not exist, this call returns an error.
Answer questions
Example Request
curl "https://api.q2open.io/v1/auth/{authId}/answer-questions" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"answers": [{
"answer": "Seattle",
"identifier": "1j5k2l1"
},
{
"answer": "Pickles",
"identifier": "3buw78h3"
}]
}'
Accepts a list of answers to the questions presented when an auth has the mfa-required
status.
HTTP Request
POST https://api.q2open.io/v1/auth/{authId}/answer-questions
Arguments
Parameter | Description |
---|---|
answers |
List of answered questions. |
Returns
Returns an object with a success
property indicating the answers were linked to the auth. Returns an error otherwise.
Delete auth
Example Request
curl "https://api.q2open.io/v1/auth/566595c8ce88ccec69328566" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-X DELETE
Example Response
{
"success": true
}
Deletes an auth
and all its items
from the account.
HTTP Request
DELETE https://api.q2open.io/v1/auth/{authId}
Arguments
Parameter | Description |
---|---|
authId |
ID of bill to delete. |
Returns
Returns an object with a success
property if the auth was deleted. If the authId
does not exist, this call returns an error.
Bill
The bill object provides you with up-to-date balance, due date, and payment history for a bill. The API allows you to retrieve, list, and check the status of a user's bills.
The bill object
Example Response
{
"_id": "579b695decea110719b1874d",
"auth": {
"_id": "579b695decea110719b1874d",
"created": "2021-10-19T19:46:21.685Z",
"status": {
"type": "verified"
},
"company": {
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
}
},
"items": ["bill"]
},
"autopay ": "unknown",
"autopaySource": "unknown",
"balance": "100.00",
"customPaymentAmount": "50.00",
"dueDate": "2018-10-25T00:00:00.000Z",
"payDate": "2018-10-25T00:00:00.000Z",
"status": {
"type": "upcoming"
},
"settings": {
"recurring": "enabled",
"schedule": "on-due-date",
"notifications": "enabled"
},
"hidden": "false",
"company": {
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
},
"schedule": "on-due-date"
}
}
Attribute | Description |
---|---|
_id |
ID of the bill. |
auth |
Auth object related to the bill. |
autopay |
Autopay field denotes if this bill is setup to autopay or not on the biller’s site. Possible values are enabled , disabled or unknown . |
autopaySource |
Autopay source field denotes how autopay was set, either by the client or by the biller’s site. Possible values are client , company or unknown . |
balance |
Current bill balance or minimum balance for bills such as credit cards or loans. |
statementBalance |
Current statement balance for bills such as credit cards or loans. |
fullBalance |
Current full balance for bills such as credit cards or loans. |
dueDate |
Current bill due date. |
customPaymentAmount |
Custom amount specified by the user to pay towards their outstanding balance. Only defined if the user has specified a custom amount to be paid. |
customLabel |
Custom label the client created for the bill. |
lastPaidAmount |
Amount of last payment. |
lastPaidOn |
The date when this bill was last paid. |
payDate |
The date when the next bill will be paid. |
status |
Status of the bill. |
company |
Company object related to the bill. |
settings |
Settings for a bill. |
settings.recurring |
Whether or not payments are scheduled automatically. Possible values are enabled , disabled . |
settings.schedule |
The schedule for when a bill payment will be made. |
settings.notifications |
Whether or not the notifications for the bill is turned on. Possible values are enabled , disabled . |
meta.accountNumber |
Account number to differentiate multiple bills on the same auth object. |
hidden |
Hidden field denotes if the bill is hidden from the bill dashboard view. |
Bill status
Syncing Response
{
"status": {
"type": "syncing"
},
"settings": {
"recurring": "enabled",
"schedule": "day-before"
}
}
Nothing Due Response
{
"status": {
"type": "zero-balance"
},
"settings": {
"recurring": "enabled",
"schedule": "day-before"
}
}
Overdue Response
{
"balance": "100.00",
"dueDate": "2016-03-25T00:00:00.000Z",
"payDate": "2016-03-24T00:00:00.000Z",
"status": {
"type": "overdue"
},
"settings": {
"recurring": "enabled",
"schedule": "day-before"
}
}
Payment Required Response
{
"status": {
"type": "payment-required"
},
"settings": {
"recurring": "enabled",
"schedule": "day-before"
},
"company": {
"requiredPayment": "card"
}
}
Payment Declined Response
{
"status": {
"type": "payment-declined"
},
"settings": {
"recurring": "enabled",
"schedule": "day-before"
}
}
Upcoming Response
{
"balance": "100.00",
"dueDate": "2018-10-25T00:00:00.000Z",
"payDate": "2018-10-24T00:00:00.000Z",
"status": {
"type": "upcoming"
},
"settings": {
"recurring": "enabled",
"schedule": "day-before"
}
}
Pending Response
{
"balance": "100.00",
"dueDate": "2018-10-25T00:00:00.000Z",
"payDate": "2018-10-24T00:00:00.000Z",
"status": {
"type": "pending"
},
"settings": {
"recurring": "enabled",
"schedule": "day-before"
}
}
Paid Response
{
"status": {
"type": "paid"
},
"lastPaidAmount": "100.00",
"lastPaidOn": "2016-01-01T00:00:00.000Z",
"settings": {
"recurring": "enabled",
"schedule": "day-before"
}
}
A bill's status.type
can be a variety of types. Each type is documented below with a description of the status and a typical use case.
syncing
Our system is currently retrieving bill data.
For Testing set status
to syncing
. balance
and dueDate
are ignored.
zero-balance
Bill data is not available yet. Most common reason is that the user hasn't received a bill. (change image)
For Testing set balance
to 0, dueDate
to a valid date, and status
to zero-balance
.
overdue
The due date for the bill has passed, and no payment has been made. Common reasons for an overdue bill are:
- A user adds a bill that is already overdue.
recurring
is enabled and the user has no payment method or their payment method's status isfailed
.recurring
is disabled and a payment has not been scheduled via the/payment/schedule
endpoint.
For Testing set balance
> 0, dueDate
to a valid date in the past, and status
to overdue
.
payment-required
The payment method specified by company.requiredPayment
is required to pay this bill. A linked payment method must be assigned before bill payments will resume. This can be done via the /payment/{paymentMethodId}/assign
endpoint.
No way to test this status as it is rare and requires the company to change its accepted payment methods after the payment method was already assigned to a bill.
payment-declined
The payment method used to pay this bill was declined. To resume bill payments, have the user try their payment method again via the /payment/{paymentMethodId}/retry
endpoint, or assign another one via the /payment/{paymentMethodId}/assign
endpoint.
For Testing first link the bill by setting balance
> 0, dueDate
to a valid date in the future, and status
to payment-declined
. Then schedule a payment for the same billId with no date.
upcoming
The user has a balance on their account and a due date that is in the future.
For Testing set balance
> 0, dueDate
to a valid date in the future, and status
to upcoming
.
pending
The system is actively trying to make a payment for the user. A pending payment cannot be canceled.
No way to test this status at this time.
paid
The user has no outstanding balance and has a last paid amount on their account.
For Testing set balance
> 0, dueDate
to a valid date in the past, and status
to paid
. Balance will become 0. dueDate
and lastPaidOn
will be the same. lastPaidAmount
will be the balance that was passed in.
Bill payment schedule
A bill's settings.schedule
is the number of days before the due date when a bill will be paid. This schedule will be followed when settings.recurring
is enabled and the company allows it.
The bill's payDate
is the date in which the next bill payment will be made. When recurring payments are enabled, the payDate
is calculated by the assigned settings.schedule
. When recurring payments are disabled, one-time payments may be scheduled on-demand via the /payment/schedule
endpoint. Available settings.schedule
options are documented below.
ten-days-before
A payment will be made ten days before the due date.
five-days-before
A payment will be made five days before the due date.
day-before
A payment will be made the day before the due date.
on-due-date
A payment will be made on the due date.
immediately
A payment will be made as soon as a new bill is received.
Retrieve bill details
Example Request
curl "https://api.q2open.io/v1/bill/566595c8ce88ccec69328566" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-G
Example Upcoming Response
{
"bill": {
"_id": "579b695decfa11012711875d",
"auth": {
"_id": "579b695decea110719b1874d",
"created": "2021-10-19T19:46:21.685Z",
"status": {
"type": "verified"
},
"company": {
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
}
},
"items": ["bill"]
},
"autopay ": "unknown",
"autopaySource": "unknown",
"balance": "100",
"dueDate": "2018-10-25T00:00:00.000Z",
"payDate": "2018-10-25T00:00:00.000Z",
"status": {
"type": "upcoming"
},
"settings": {
"recurring": "enabled",
"schedule": "on-due-date",
"notifications": "enabled"
},
"hidden": "false",
"company": {
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
},
"schedule": "on-due-date"
}
},
"payments": []
}
Example Paid Response
{
"bill": {
"_id": "579b695decfa11012711875d",
"auth": {
"_id": "579b695decea110719b1874d",
"created": "2021-10-19T19:46:21.685Z",
"status": {
"type": "verified"
},
"company": {
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
}
},
"items": ["bill"]
},
"status": {
"type": "paid"
},
"hidden": "false",
"lastPaidAmount": "100",
"lastPaidOn": "2016-01-01T00:00:00.000Z",
"settings": {
"recurring": "enabled",
"schedule": "on-due-date",
"notifications": "enabled"
},
"autopay ": "unknown",
"autopaySource": "unknown",
"company": {
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
},
"schedule": "on-due-date"
}
},
"payments": [{
"amount": "123.12",
"paidOn": "2016-01-01T00:00:00.000Z"
},{
"amount": "153.19",
"paidOn": "2016-01-02T00:00:00.000Z"
}]
}
Retrieve details about a bill including outstanding balance, due date, settings, status, and payment history.
HTTP Request
GET https://api.q2open.io/v1/bill/{billId}
Arguments
Parameter | Description |
---|---|
billId |
ID of bill to retrieve. |
Returns
Returns details for a bill if a valid billId
was provided. Returns an error otherwise.
List all bills
Example Request
curl https://api.q2open.io/v1/bill/list/579b695decfa11012711875d
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e"
-G
Example Response
{
"data": [
{
"bill": {
"_id": "579b695decfa11012711875d",
"auth": {
"_id": "579b695decea110719b1874d",
"created": "2021-10-19T19:46:21.685Z",
"status": {
"type": "verified"
},
"company": {
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
}
},
"items": ["bill"]
},
"autopay ": "unknown",
"autopaySource": "unknown",
"balance": "100.00",
"customPaymentAmount": "50.00",
"dueDate": "2018-10-25T00:00:00.000Z",
"payDate": "2018-10-25T00:00:00.000Z",
"status": {
"type": "upcoming"
},
"settings": {
"recurring": "enabled",
"schedule": "on-due-date",
"notifications": "enabled"
},
"hidden": "false",
"company": {
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
},
"schedule": "on-due-date"
}
},
"payments": []
},
{
"bill": {
"_id": "579b695decfa11012711875d",
"auth": {
"_id": "579b695decea110719b1874d",
"created": "2021-10-19T19:46:21.685Z",
"status": {
"type": "verified"
},
"company": {
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
}
},
"items": ["bill"]
},
"autopay ": "unknown",
"autopaySource": "unknown",
"hidden": "false",
"status": {
"type": "paid"
},
"lastPaidAmount": "100",
"lastPaidOn": "2016-01-01T00:00:00.000Z",
"settings": {
"recurring": "enabled",
"schedule": "day-before",
"notifications": "enabled"
},
"company": {
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
}
}
},
"payments": [{
"amount": "123.12",
"paidOn": "2016-01-01T00:00:00.000Z"
},{
"amount": "153.19",
"paidOn": "2016-01-02T00:00:00.000Z"
}]
}
]
}
Retrieves a list of client's bills.
HTTP Request
GET https://api.q2open.io/v1/bill/list/{clientId}
Arguments
Parameter | Description |
---|---|
clientId |
ID of the client to retrieve bills for. |
Returns
A dictionary with a data
property that contains an array of bill details.
List all bills by partnerId
Example Request
curl https://api.q2open.io/v1/bill/listByPartner/616f208da973a0828ecd015c
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e"
-G
Example Response
{
"data": [
{
"bill": {
"_id": "579b695decfa11012711875d",
"auth": {
"_id": "616f208da973a0828ecd0166",
"created": "2021-10-19T19:46:21.685Z",
"status": {
"type": "verified"
},
"company": {
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
},
"schedule": "on-due-date"
},
"items": ["bill"]
},
"balance": "100.00",
"customPaymentAmount": "50.00",
"dueDate": "2018-10-25T00:00:00.000Z",
"payDate": "2018-10-25T00:00:00.000Z",
"status": {
"type": "upcoming"
},
"autopay ": "unknown",
"autopaySource": "unknown",
"settings": {
"recurring": "enabled",
"schedule": "on-due-date",
"notifications": "enabled"
},
"hidden": "false",
"company": {
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
},
"schedule": "on-due-date"
}
},
"payments": [],
"partnerUserId": "616f208da973a0828ecd0164",
"partnerId": "616f208da973a0828ecd015c"
},
]
}
Retrieves a list of partner's active bills.
HTTP Request
GET https://api.q2open.io/v1/bill/listByPartner/{partnerId}
Arguments
Parameter | Description |
---|---|
partnerId |
ID of the partner to retrieve bills for. |
Returns
A dictionary with a data
property that contains an array of bill details.
Company
Company objects allow you to authenticate bills with your users. The API allows you to retrieve and search for companies.
The company object
Sample Response
{
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"categories": ["streaming"],
"status": "operational",
"fullyAutomatedBill": true,
"fullyAutomatedCardSwap": false,
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false,
"svg": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.svg",
"color": "FF041F"
}
},
"requiredPayment": "bank",
"schedule": "on-due-date",
"additionalPaymentOptions": [{
"type": "custom-payment-amount",
"settings": {
"canExceedBalance": false
}
}]
"auth": {
"urls": {
"login": "https://www.netflix.com/Login",
"signup": "https://www.netflix.com"
},
"loginFields": [{
"placeholder": "Username",
"formType": "text",
"name": "username",
"label": "Username"
}, {
"placeholder": "Password",
"formType": "password",
"name": "password",
"label": "Password"
}]
},
"geo": {
"lat": 30.70,
"lng": -95.53,
"state_short": "TX",
"state_long": "Texas",
"zipcode": "77340"
},
"fees": {
"ach": {
"rate": 1.5,
"percentage": false
},
"cards": {
"american express": {
"credit": {
"rate": 1.5,
"percentage": false
}
},
"discover": {
"credit": {
"rate": 1.5,
"percentage": false
},
"debit": {
"rate": 1.5,
"percentage": false
}
},
"mastercard": {
"credit": {
"rate": 1.5,
"percentage": false
},
"debit": {
"rate": 1.5,
"percentage": false
}
},
"visa": {
"credit": {
"rate": 1.5,
"percentage": false
},
"debit": {
"rate": 1.5,
"percentage": false
}
},
"amex": {
"debit": {
"rate": 1.5,
"percentage": false
}
}
}
}
}
Attribute | Description |
---|---|
_id |
ID of the company. |
name |
Name of the company. |
categories |
Categories of the company. A company may fall under multiple categories. |
status |
The operational status of the company at any given moment of time. Possible values are operational , maintenance . |
fullyAutomatedBill |
If true , then bill aggregation and payments are fully automated. Possible values are true , false . |
fullyAutomatedCardSwap |
If true , then swapping a card is fully automated. Possible values are true , false . |
logo |
Company logo object. |
logo.url |
URL of the company logo. |
logo.background |
If this is true , then the logo looks best as a background image. |
logo.svg |
Company logo svg object. |
logo.svg.url |
URL of the company svg logo. |
logo.svg.color |
Hex color of the company logo. |
requiredPayment |
If a specific payment method type is required by this company, this will be defined. Possible values are bank , card . |
userPresenceRequired |
If the company requires that the user is present to pass through any security flows. See best practices in the Connect documentation. |
schedule |
The bill payment schedule this company follows. If this parameter is set, the schedule for a bill linked to this company may not be changed. Typically subscription companies such as Netflix have this parameter set since payments must be made on a specific date. |
additionalPaymentOptions |
Present when the company provides additional payment options that allow users to make payments towards their outstanding balance. |
fees |
The surcharge object. Possible child objects are ach , cards |
fees.ach |
Present when the company applies surcharges to ACH payments. |
fees.ach.percentage |
If the ACH surcharge is a percentage of the payment amount. |
fees.ach.rate |
Either a dollar amount or a percentage amount. |
fees.cards |
Present when the company applies surcharges to card payments. Possible child objects are american express , discover , mastercard , and visa , referred to below as {cardBrand} . See example company response. |
fees.cards.{cardBrand} |
Possible child objects are credit or debit , referred to below as {cardType} . |
fees.cards.{cardBrand}.{cardType}.percentage |
If the surcharge is a percentage of the payment amount. |
fees.cards.{cardBrand}.{cardType}.rate |
Either a dollar amount or a percentage amount. |
auth |
Company auth fields. |
auth.urls |
Company Auth Urls (login URL is always available, but the others can by null). |
auth.urls.login |
Login URL. |
auth.urls.signup |
Signup URL. |
auth.urls.forgotPassword |
Forgot password URL. |
auth.urls.forgotUsername |
Forgot username URL. |
auth.loginFields |
Form fields for credentials. |
auth.loginFields.placeholder |
Input placeholder field. |
auth.loginFields.formType |
Input type field. |
auth.loginFields.name |
Input name field. |
auth.loginFields.label |
Label for input . |
geo |
Geo based location (not available for regional or national company). |
geo.lat |
Latitude coordinate. |
geo.lng |
Longitude coordinate. |
geo.stateShort |
Abbreviated state name. |
geo.stateLong |
Full state name. |
geo.zipcode |
Zipcode. |
geo.address |
Formatted address. |
Company logos
The Q2 Biller Direct API provides image URL's for each company's logo. For our most popular companies, we also provide a white svg logo, along with the hex color of the company's brand. There are three ideal ways of presenting these logos in your apps.
When the
company.logo.svg
is available, the svg logo looks best on thecompany.logo.svg.color
background.When the
company.logo.svg
is not available and thecompany.logo.background
field is set tofalse
, the logo looks best on a white background.When the
company.logo.svg
is not available and thecompany.logo.background
field is set totrue
, the logo looks best as a background image with the company name overlaid on top.
Company categories
Example Request
curl "https://api.q2open.io/v1/company/categories" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-G
Example Response
{
"data": [{
"name": "Electric",
"type": "electric"
}]
}
Retrieve a list of company categories you can use to search for companies by category type
.
HTTP Request
GET https://api.q2open.io/v1/company/categories
Returns
A dictionary with a data
property that contains an array of company categories.
Retrieve a company
Example Request
curl "https://api.q2open.io/v1/company/566595c8ce88ccec69328566" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-G
Example Response
{
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"categories": ["streaming"],
"status": "operational",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false,
"svg": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.svg",
"color": "FF041F"
}
},
"requiredPayment": "bank",
"schedule": "on-due-date",
"auth": {
"urls": {
"login": "https://www.netflix.com/Login",
"signup": "https://www.netflix.com"
},
"loginFields": [{
"placeholder": "Username",
"formType": "text",
"name": "username",
"label": "Username"
}, {
"placeholder": "Password",
"formType": "password",
"name": "password",
"label": "Password"
}]
},
"geo": {
"lat": 30.70,
"lng": -95.53,
"state_short": "TX",
"state_long": "Texas",
"zipcode": "77340"
}
}
Retrieves the company with the given ID.
HTTP Request
GET https://api.q2open.io/v1/company/{companyId}
Arguments
Parameter | Description |
---|---|
companyId |
ID of company to retrieve. |
Returns
Returns a company object if a valid companyId
was provided. Returns an error otherwise.
Search for companies
Example Requests
curl "https://api.q2open.io/v1/company/search" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"query": "Netflix"
"paginateResults": "true",
"pageSize": "25",
"pageNumber": "1",
"products": "['cardswap']"
}'
curl "https://api.q2open.io/v1/company/search" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"category": "gas"
}'
curl "https://api.q2open.io/v1/company/search" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"geo": {
"lat": 40.233845,
"lng": -111.65852
}
}'
Example Response
{
"data": [
{
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"categories": ["streaming"],
"status": "operational",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false,
"svg": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.svg",
"color": "FF041F"
}
},
"requiredPayment": "bank",
"schedule": "on-due-date",
"auth": {
"urls": {
"login": "https://www.netflix.com/Login",
"signup": "https://www.netflix.com"
},
"loginFields": [{
"placeholder": "Username",
"formType": "text",
"name": "username",
"label": "Username"
}, {
"placeholder": "Password",
"formType": "password",
"name": "password",
"label": "Password"
}]
},
"geo": {
"lat": 30.70,
"lng": -95.53,
"state_short": "TX",
"state_long": "Texas",
"zipcode": "77340"
}
}
],
"resultCount": 1
}
Search for companies by name, category, or nearby a geo coordinate.
HTTP Request
POST https://api.q2open.io/v1/company/search
Arguments
Parameter | Description |
---|---|
query |
The text string on which to search companies by name. |
category |
Category type retrieved from the /company/categories endpoint. |
geo |
Geo coordinates to search companies by location. |
geo.lat |
Latitude coordinate. |
geo.lng |
Longitude coordinate. |
paginateResults |
Boolean that enables returning paginated results. |
pageSize |
Used with paginateResults to set page size (Max 100). |
pageNumber |
Used with paginateResults to set which page of results gets returned in the data. |
products |
Product type that is enabled on the companies. This parameter is to be an array with string values biller-direct and cardswap as options. |
Returns
A dictionary with a data
property that contains an array of company objects that match the provided search filters. If paginateResults is true, this also includes resultCount
which is the total count of matching companies.
Payment
In order to make payments towards a user's bill, they must first link a payment method using the /payment
endpoint. By default, after a payment method is linked, payments will be made towards a user's bills on time. The API allows you to add and retrieve a user's payment method, as well as make payments towards a bill's outstanding balance and cancel a scheduled payment.
The card object
Example Response
{
"number": "XXXX0005",
"brand": "american express",
"type": "credit",
"expDate": "2019-06-01T12:00:00.000Z"
}
Attribute | Description |
---|---|
number |
Masked card number. |
brand |
Card brand. Possible values are visa , mastercard , american express , etc. |
type |
Card type. Possible values are credit , debit . |
expDate |
Card expiration date. |
The bank object
Example Response
{
"routingNumber": "XXXX0002",
"accountNumber": "XXXX0021",
"type": "checking"
}
Attribute | Description |
---|---|
routingNumber |
Masked routing number. |
accountNumber |
Masked account number. |
type |
Bank account type. Possible values are checking , savings . |
The payment method object
Example Response
{
"_id": "580e3e11dec21e861b5a3719",
"type": "card",
"identifier": "optional_custom_identifier",
"status": "verified",
"default": true,
"card": {
"number": "XXXX0005",
"brand": "american express",
"type": "credit",
"expDate": "2019-06-01T12:00:00.000Z"
},
"assignedBills": [ "580e3e11dec21e861b5a3719" ]
}
Attribute | Description |
---|---|
_id |
ID of the payment method. |
type |
The type of the payment method on file. Possible values are card , bank . |
identifier |
Optional custom identifier for external system correlation. |
status |
The status of the payment method on file. Possible values are verified , declined . |
default |
If this is the default payment method. Default means that it will pay any bills not specifically assigned a payment method. |
assignedBills |
A list of bill ID's this payment method was specifically assigned to. |
card |
Card object |
bank |
Bank object |
Payment status
A payment method can have one of three statuses. Each type is documented below with a description of the status and a typical use case.
verified
The payment method on file is verified and eligible to make payments.
declined
The payment method on file is not eligible to make payments. This may happen for a number of reasons including:
- Insufficient funds
- Expired card
- Closed bank account
When a user's payment method fails to pay a bill, we set their payment method status as declined
. While their status is declined
no bill payments will be made in behalf of the user. To address this issue, you may take one of the following courses of action:
- Link a new payment method via the
/payment
endpoint. - Retry the payment method via the
/payment/{paymentMethodId}/retry
endpoint.
Declined payment prompt
If their payment method continues to be declined, it will be removed from their account. If the removed payment method was the default, the user will need to link a new payment method or choose another payment method on file as their default before bill payment services resume.
Add a payment method
Example Card Request
curl "https://api.q2open.io/v1/payment" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"clientId": "56e1ddbd1a05319bc198d36f",
"paymentType": "card",
"identifier": "optional_custom_identifier",
"cardNumber": "378282246310005",
"cardCode": "218",
"expMonth": "10",
"expYear": "2017",
"zipcode": "12345",
"name": "Demo User",
"setAsDefault": true,
"customLabel": "Entertainment Rewards Card"
}'
Example Bank Request
curl "https://api.q2open.io/v1/payment" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"clientId": "56e1ddbd1a05319bc198d36f",
"paymentType": "bank",
"identifier": "optional_custom_identifier",
"routingNumber": "021000021",
"accountNumber": "9900000002",
"accountType": "checking",
"name": "Demo User",
"customLabel": "For Utilities"
}'
Example Response
{
"paymentMethodId": "56e1ddbd1a05319bc198d36f"
}
Add a payment method to a user.
HTTP Request
POST https://api.q2open.io/v1/payment
Arguments
Parameter | Description |
---|---|
clientId |
ID of the client to add a payment method to. |
paymentType |
Type of payment. Possible values are card , bank . |
identifier |
Optional custom identifier for external system correlation. |
cardNumber |
Credit card number. |
cardCode |
Credit card CVV. |
expMonth |
Credit card expiration month formatted as XX . |
expYear |
Credit card expiration year formatted as XXXX . |
zipcode |
Credit card zipcode. |
name |
The name as it appears on the payment account. |
routingNumber |
Bank routing number. |
accountNumber |
Bank account number. |
accountType |
Type of bank account. Possible values are checking , savings . |
setAsDefault |
Set this payment method as the default. |
customLabel |
Used for letting the user set a custom display name for this account. |
Returns
Returns an object with a paymentMethodId
property if the payment method was successfully added. Returns an error otherwise.
List all payment methods
Example Request
curl "https://api.q2open.io/v1/payment/list/566595c8ce88ccec69328566" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-G
Example Response
{
"data": [
{
"_id": "580e3754dec21e861b5a3718",
"type": "card",
"identifier": "optional_custom_identifier",
"status": "verified",
"default": true,
"name": "Demo User",
"card": {
"number": "XXXX4242",
"brand": "visa",
"type": "credit",
"expDate": "2016-12-01T12:00:00.000Z"
}
},
{
"_id": "580e3e11dec21e861b5a3719",
"type": "bank",
"identifier": "optional_custom_identifier",
"status": "declined",
"name": "Demo User",
"bank": {
"routing": "XXXX2531",
"account": "XXXX4124",
"type": "checking"
}
}
]
}
Retrieve a list of payment methods on file for a client.
HTTP Request
GET https://api.q2open.io/v1/payment/list/{clientId}
Arguments
Parameter | Description |
---|---|
clientId |
ID of client to retrieve payment methods for. |
Returns
A dictionary with a data
property that contains an array of payment method objects.
Delete payment method
Example Request
curl "https://api.q2open.io/v1/payment/566595c8ce88ccec69328566" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-X DELETE
Example Response
{
"success": true
}
Delete a payment method on file for bill payments. If a payment was made within the last 24 hours with this payment method, an error will be returned. Q2 requires a 24 hour time span after a payment has been made before a payment method can be deleted.
HTTP Request
DELETE https://api.q2open.io/v1/payment/{paymentMethodId}
Arguments
Parameter | Description |
---|---|
paymentMethodId |
ID of payment method to delete. |
Returns
Returns an object with a success
property if the payment method was deleted. Returns an error otherwise.
Retry payment method
Sample Request
curl "https://api.q2open.io/v1/payment/566595c8ce88ccec69328566/retry" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-X POST
Example Response
{
"success": true
}
Retry a declined
payment method on file for bill payments.
HTTP Request
POST https://api.q2open.io/v1/payment/{paymentMethodId}/retry
Arguments
Parameter | Description |
---|---|
paymentMethodId |
ID of payment method to retry. |
Returns
Returns an object with a success
property if the payment method will be retried. Returns an error otherwise.
Assign payment method
Example Request
curl "https://api.q2open.io/v1/payment/566595c8ce88ccec69328566/assign" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"billId": "566595c8ce88ccec69328566",
}'
-X POST
Example Response
{
"success": true
}
Assign a linked payment method to pay a specific bill. This is required when a company's requiredPayment
is defined as card
or bank
.
HTTP Request
POST https://api.q2open.io/v1/payment/{paymentMethodId}/assign
Arguments
Parameter | Description |
---|---|
paymentMethodId |
ID of payment method to assign. |
billId |
ID of bill to assign payment method to. |
Returns
Returns an object with a success
property if the payment method was assigned. Returns an error otherwise.
Update payment settings
Example Request
curl "https://api.q2open.io/v1/payment/settings" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"billId": "566595c8ce88ccec69328566",
"recurring": "enabled",
"schedule": "five-days-before"
}'
-X POST
Example Response
Update payment settings for a bill.
Some subscription companies, such as Netflix, Hulu, and Spotify require recurring payments to be enabled. If a request to the /payment/settings
endpoint is made for one of these companies, an error will be returned and recurring payments will not be disabled.
HTTP Request
POST https://api.q2open.io/v1/payment/settings
Arguments
Parameter | Description |
---|---|
billId |
ID of bill to update payment settings for. |
recurring |
Whether recurring payments should be enabled or disabled . |
schedule |
The bill payment schedule for payments |
Returns
Returns an object with a success
property if payment settings were successfully updated. Returns an error otherwise.
Schedule payment
Example Request
curl "https://api.q2open.io/v1/payment/schedule" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"billId": "566595c8ce88ccec69328566",
"payDate": "2018-10-25T00:00:00.000Z"
}'
{
"apiKey": "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e",
"billId": "566595c8ce88ccec69328566",
"payDate": "2018-10-25T00:00:00.000Z"
}
Example Response
{
"success": true
}
Schedule an on-demand payment towards a bill's outstanding balance.
HTTP Request
POST https://api.q2open.io/v1/payment/schedule
Arguments
Parameter | Description |
---|---|
billId |
ID of bill to schedule payment for. |
date (optional) |
An ISO 8601 formatted date that sets what day this bill will be paid. If no date is specified, the bill is scheduled to be paid immediately. |
Returns
Returns an object with a success
property if a payment was scheduled. Returns an error otherwise.
Cancel payment
Example Request
curl "https://api.q2open.io/v1/payment/cancel" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"billId": "566595c8ce88ccec69328566",
}'
{
"billId": "566595c8ce88ccec69328566",
}
Example Response
{
"success": true
}
Cancel a scheduled payment for a bill.
HTTP Request
POST https://api.q2open.io/v1/payment/cancel
Arguments
Parameter | Description |
---|---|
billId |
ID of bill to cancel payment for. |
Returns
Returns an object with a success
property if the payment was canceled. Returns an error otherwise.
Client
To authenticate and interact with the endpoints on behalf of a given user, a clientId
is required.
Create Client
Example Request
curl "https://api.q2open.io/v1/client" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"identifier": "Bk0zwVx1Z",
"meta": {
"firstName": "Demo",
"lastName": "User",
"email": "demo@demo.com",
"phone": "123-123-1234",
"address1": "123 Api St.",
"address2": "P.O. Box 283",
"city": "Demo",
"state": "Q2",
"zipcode": "12345"
}
}'
Example Response
{
"clientId": "579b695decfa11012711875d"
}
Creates or returns an existing client to be used with requests.
If a client already exists with the same identifier
included in the request, the existing clientId
is returned.
HTTP Request
POST https://api.q2open.io/v1/client
Arguments
Parameter | Description |
---|---|
identifier |
A unique identifier that represents a user in your system. |
meta |
Additional information about the user in your system. |
Returns
Returns an object with a clientId
property that can be used for requests.
Create Token
Example Request
curl "https://api.q2open.io/v1/client/create-token" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"identifier": "Bk0zwVx1Z",
"accessTokenExpiresIn": 3600
}'
Example Response
{
"token": "566595c8ce88ccec69328566c8ce8595c8"
}
Create a token to be used for SSO into applications.
When creating subsequent tokens for an existing client
, be sure to use the same identifier
value. If a client already exists with this identifier
, then any actions taken within the context of a Product. will be linked to that client.
HTTP Request
POST https://api.q2open.io/v1/client/create-token
Arguments
Parameter | Description |
---|---|
identifier |
A unique identifier that represents a user in your system. |
nonce |
Optional boolean specifying whether the token is for one time use. Default is false. |
expiration |
An ISO 8601 formatted date that sets when this token will expire. If no expiration is specified, the token will expire after 24 hours. |
accessTokenExpiresIn |
Optional number of seconds that an access token issued using the SSO token is valid. Default is 1 hour (3600). |
Returns
Returns an object with a token
property that can be used to SSO into applications.
Revoke Tokens
Example Request
curl "https://api.q2open.io/v1/client/revoke-tokens" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"identifier": "Bk0zwVx1Z",
"clientToken": "566595c8ce88ccec69328566c8ce8595c8"
}'
Example Response
{
"success": true
}
Revokes client SSO and access tokens associated with either a client or client SSO token. When a token is revoked, it can no longer be used to access the Biller Direct API.
Either a client identifier
or clientToken
must be provided.
If a client identifier
is provided, all current SSO and access tokens associated with that client will be revoked.
If a clientToken
from Create Token is provided, that token and any related access tokens will be revoked.
If both parameters are passed, the clientToken
parameter is ignored.
HTTP Request
POST https://api.q2open.io/v1/client/revoke-tokens
Arguments
Parameter | Description |
---|---|
identifier |
Optional A unique identifier that represents a user in your system. |
clientToken |
Optional The client SSO token produced by a call to Create Token. |
Returns
Returns an object with a success
property.
Sync Client
Example Request
curl "https://api.q2open.io/v1/client" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"client": {
"identifier": "Bk0zwVx1Z",
"meta": {
"firstName": "Demo",
"lastName": "User",
"email": "demo@demo.com",
"phone": "123-123-1234",
"address1": "123 Api St.",
"address2": "P.O. Box 283",
"city": "Demo",
"state": "Q2",
"zipcode": "12345"
}
},
"token": {
"expiration": "2025-01-30T00:00:00.000Z"
},
"cards": [{
"identifier": "fiId123",
"cardNumber": "4111111111111111",
"cardCode": "123",
"cardType": "credit",
"cardBrand": "visa",
"expMonth": "02",
"expYear": "2040",
"zipcode": "12345",
"name": "Demo User",
"setAsDefault": "true",
"customLabel": "Entertainment Rewards Card"
}]
}'
Example Response
{
"clientId": "579b695decfa11012711875d",
"ssoToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWJqZWN0IjoiNWYwMzY1YTdhZjkyODg5NjhiNTNiM2QzIiwiaWF0IjoxNTk0MDU4OTQ1LCJleHAiOjE1OTQxNDUzNDUsImlzcyI6IlBBWUJJREVUIiwic3ViIjoiNWYwMzY1YTdhZjkyODg5NjhiNTNiM2QzIn0.kO_x9cZRlhI4dyGarOPI1w2gW2QI-ObqyKFdXKs64Ek",
"cards": [{
"paymentMethodId": "55942f330cfcfd6c4ed529d9",
"identifier": "fiId123"
}]
}
Syncs client data and card information by combining the create client, create token, and add payment method calls.
If a client already exists with the same identifier
included in the request, the existing clientId
is returned.
HTTP Request
POST https://api.q2open.io/v1/client/sync
Arguments
Parameter | Description |
---|---|
client |
The object used from the create client call. |
token |
The object used from the create token call. |
cards |
A list of cards to be added to the client, as specified in the add payment method call. You can specify the cardType and cardBrand parameters for a much faster call speed. Possible values for cardType are credit , debit . Possible values for cardBrand are american express , discover , maestro , mastercard , uatp , visa . |
Returns
Returns an object with a clientId
property that can be used for requests, an ssoToken
that can be used with white-label products, and a cards
array that includes a list of objects that include the paymentMethodId
of the created card and identifier
passed in.
Swap
Enables account holders to automatically apply new debit or credit card information across their favorite subscription and digital point-of-sale services.
The swap object
Example Response
{
"_id": "5b4cdadf8ea75a6602ff82bb",
"status": {
"type": "completed"
},
"auth": {
"_id": "5b4cdade36c0c10108a57405",
"status": {
"type": "verified"
}
},
"company": {
"_id": "5522f59264f5785929aa1c42",
"name": "Hulu",
"status": "operational",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/a3c89f48378c84713fb31ce0e97bfa15.png",
"background": false
}
},
"paymentMethod": {
"_id": "5b296e67a15d4e0001174fc2",
"type": "card",
"name": "Demo User",
"status": "verified",
"default": true,
"card": {
"number": "XXXX7989",
"bin": "41474002",
"brand": "visa",
"type": "credit",
"expDate": "2023-06-01T12:00:00.000Z"
}
}
}
Attribute | Description |
---|---|
_id |
ID of the swap. Unavailable when the status.type is pending . |
status |
Status of the swap. |
auth |
Auth object related to the swap. |
company |
Company object related to the swap. |
paymentMethod |
Payment method object to be swapped in. |
Swap status
In Progress Response
{
"status": {
"type": "in-progress"
}
}
Hold Response
{
"status": {
"type": "hold"
}
}
Completed Response
{
"status": {
"type": "completed"
}
}
Card On File Response
{
"status": {
"type": "card-on-file"
}
}
A swap status.type
indicates the current state of a request to swap a payment method with a particular company.
in-progress
The swap of the payment method is currently in progress.
For Testing set status
to in-progress
. balance
and dueDate
are ignored.
hold
The swap of the payment method is currently on hold as described in the Auth Status.
For Testing refer to auth hold.
completed
The swap of the payment method has been completed successfully.
For Testing set status
to completed
. balance
and dueDate
are ignored.
card-on-file
The swap of the payment method has been completed with the detection that the card was already on file.
For Testing set status
to card-on-file
. balance
and dueDate
are ignored.
Add a swap
Example Request
curl "https://api.q2open.io/v1/swap/create" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-H "Content-Type: application/json" \
-d '{
"authId": "566595c8ce88ccec69328566",
"paymentMethodId": "5b4cdade36c0c10108a57405"
}'
HTTP Request
POST https://api.q2open.io/v1/swap/create
Arguments
Parameter | Description |
---|---|
authId |
ID of auth to create a swap for. |
paymentMethodId |
ID of payment method to link to the swap. |
Returns
Returns an object with a success
property if the swap was created. Returns an error otherwise.
Company list
Example Request
curl "https://api.q2open.io/v1/swap/companies" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-G
Example Response
{
"data": [
{
"_id": "579b695decea110719b1874d",
"name": "Netflix",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false,
"svg": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.svg",
"color": "FF041F"
}
},
"requiredPayment": "bank",
"schedule": "on-due-date",
"auth": {
"urls": {
"login": "https://www.netflix.com/Login",
"signup": "https://www.netflix.com"
},
"loginFields": [{
"placeholder": "Username",
"formType": "text",
"name": "username",
"label": "Username"
}, {
"placeholder": "Password",
"formType": "password",
"name": "password",
"label": "Password"
}]
},
"geo": {
"lat": 30.70,
"lng": -95.53,
"state_short": "TX",
"state_long": "Texas",
"zipcode": "77340"
}
}
]
}
Retrieve a list of companies that support swaps.
HTTP Request
GET https://api.q2open.io/v1/swap/companies
Returns
A dictionary with a data
property that contains an array of company objects that support swaps.
List all swaps
Example Request
curl "https://api.q2open.io/v1/swap/list/566595c8ce88ccec69328566" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-G
Example Response
{
"data": [
{
"_id": "5b4cdadf8ea75a6602ff82bb",
"status": {
"type": "completed"
},
"auth": {
"_id": "5b4cdade36c0c10108a57405",
"status": {
"type": "verified"
}
},
"company": {
"_id": "5522f59264f5785929aa1c42",
"name": "Hulu",
"status": "operational",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/a3c89f48378c84713fb31ce0e97bfa15.png",
"background": false
}
},
"paymentMethod": {
"_id": "5b296e67a15d4e0001174fc2",
"type": "card",
"name": "Demo User",
"status": "verified",
"card": {
"number": "XXXX7989",
"bin": "41474002",
"brand": "visa",
"type": "credit",
"expDate": "2023-06-01T12:00:00.000Z"
}
}
}
]
}
Retrieves a list of client's swaps.
HTTP Request
GET https://api.q2open.io/v1/swap/list/{clientId}
Arguments
Parameter | Description |
---|---|
clientId |
ID of client to retrieve swaps for. |
Returns
A dictionary with a data
property that contains an array of swap objects.
Partner
Partner API endpoints allow partner-specific information to be retrieved.
Get public keys
Example Request
curl "https://api.q2open.io/v1/partner/public-keys" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-G
Example Response
{
"keys": [
{
"kty": "RSA",
"n": "yn8Ek5WFlw0YIsXpjqC7_MCN4OfUAUVp3tje...",
"e": "AQAB",
"use": "enc",
"kid": "5b4cdadf8ea75a6602ff82bb",
"x5c": "MIIFczCCBFugAwIBAgISBB/csS+OpHRTGG..."
},
{
"kty": "RSA",
"n": "yn8Ek5WFlw0YIsXpjqC7_MCN4OfUAUVp33ds...",
"e": "AQAB",
"use": "enc",
"kid": "5b4cdadf8ea75a6602ff82bc",
"x5c": "MIIFczCCBFugAwIBAgISBB/csS+OpHRTGG..."
}
]
}
Retrieves an array of active public keys from the current partner for request encryption. Partner keys are managed in the Nexus application.
HTTP Request
GET https://api.q2open.io/v1/partner/public-keys
Returns
A response with a keys
array that contains active partner public keys in JWK Set format.
Get specific public key
Example Request
curl "https://api.q2open.io/v1/partner/public-keys/{keyId}" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-G
Example Response
{
"kty": "RSA",
"n": "yn8Ek5WFlw0YIsXpjqC7_MCN4OfUAUVp3tje...",
"e": "AQAB",
"use": "enc",
"kid": "5b4cdadf8ea75a6602ff82bb",
"x5c": "MIIFczCCBFugAwIBAgISBB/csS+OpHRTGG..."
}
Retrieves a specific public key from the current partner for request encryption. Partner keys are managed in the Nexus application.
HTTP Request
GET https://api.q2open.io/v1/partner/public-keys/{keyId}
Arguments
Parameter | Description |
---|---|
keyId |
ID of the key to retrieve. |
Returns
A response with the latest public key content in JWK format.
Get latest public key
Example Request
curl "https://api.q2open.io/v1/partner/public-keys/latest" \
-H "Authorization: Bearer dc220490-e6ee-11e5-8a94-e7385a8d929e" \
-G
Example Response
{
"kty": "RSA",
"n": "yn8Ek5WFlw0YIsXpjqC7_MCN4OfUAUVp3tje...",
"e": "AQAB",
"use": "enc",
"kid": "5b4cdadf8ea75a6602ff82bb",
"x5c": "MIIFczCCBFugAwIBAgISBB/csS+OpHRTGG..."
}
Retrieves the latest public key from the current partner for request encryption. Partner keys are managed in the Nexus application.
HTTP Request
GET https://api.q2open.io/v1/partner/public-keys/latest
Returns
A response with the latest public key content in JWK format.
Events
Events are our way of letting you know when something interesting happens on behalf of your users.
When an interesting event occurs, we create a new Event
object. For example, when a new bill is received, we create a bill.update
event; when a bill payment is sent, we create a bill.payment
event.
We have a system for sending the event objects directly to an endpoint on your server, called webhooks. Webhooks are managed in Nexus.
The event object
Example Response
{
"_id": "580e3e11dec21e861b5a3719",
"type": "bill.update",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"sessionId" : "your-session-id-if-supplied-12345"
"identifier": "example-id-123",
"partnerId": "55942f330cfcfd6c4ed529d9",
"payload": {
"resource": {
"id": "579b695decfa11012711875d",
"type": "bill"
},
"data": {
"previous": {
"balance": "25.21"
},
"current": {
"balance": "52.11"
}
}
}
}
Attribute | Description |
---|---|
_id |
ID of the event. |
type |
Description of the event: e.g. bill.issued , bill.updated , etc. |
clientId |
The id of the client to which the event pertains. |
partnerId |
The id of the partner to which the event pertains. |
sessionId |
Your internal identifier associated with the client session as described in Sessions. |
identifier |
Your internal identifier associated with the client . |
created |
An ISO 8601 formatted date of when this event was created. |
payload |
Object containing data associated with the event.. |
payload.resource |
Object containing data associated with the resource of the event. |
payload.resource.id |
ID of the resource associated with the event. |
payload.resource.type |
The type of resource associated with the event. Possible values are bill . |
payload.data |
Object containing unique attributes per type as described in types of events. |
Types of events
This is a list of all the types of events we currently send. We may add more at any time, so you shouldn't rely on only these types existing in your code.
You'll notice that these events follow a pattern: resource.event
. Our goal is to design a consistent system that makes things easier to anticipate and code against.
Each event object includes a payload.data
property which contains unique values for each type
of event. Each event type below describes these unique values.
Auth success
Example
auth.success
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "auth.success",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "client",
"id": "579b695decfa110127118752"
},
"data": {
"auth" : {
"_id" : "5b157888cb7e60000bfcaa41",
"items" : [
"bill"
],
"company" : {
"_id" : "55942f330cfcfd6c4ed529d8",
"name" : "Geico"
},
"status" : {
"type" : "verified"
}
}
}
}
}
}
When a client has successfully completed the authentication process.
Attribute | Description |
---|---|
type |
auth.success |
payload.resource.id |
The ID of the client who was authenticating. |
payload.resource.type |
The type of resource referred to by the resource.id. Value: client . |
payload.data.auth |
The auth object linked to this resource. |
Auth invalid
Example
auth.invalid
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "auth.invalid",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "auth",
"id": "579b695decfa11012711875d"
},
"data": {
"company" : {
"_id" : "55942f330cfcfd6c4ed529d8",
"name" : "Geico"
}
}
}
}
}
When the auth's credentials are no longer valid and need to be reauthenticated.
Attribute | Description |
---|---|
type |
auth.invalid |
payload.resource.id |
The ID of the auth that needs to be reauthenticated. |
payload.resource.type |
The type of resource referred to by the resource.id. Value: auth . |
payload.data.company |
The company object linked to this resource. |
Auth deleted
Example
auth.deleted
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "auth.deleted",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "auth",
"id": "579b695decfa110127118752"
},
"data": {
"company" : {
"_id" : "55942f330cfcfd6c4ed529d8",
"name" : "Geico"
}
}
}
}
}
When a client deletes an auth.
Attribute | Description |
---|---|
type |
auth.deleted |
payload.resource.id |
The ID of the auth that was deleted. |
payload.resource.type |
The type of resource referred to by the resource.id. Value: auth . |
payload.data.company |
The company object linked to this resource. |
Auth hold
Example
auth.hold
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "auth.hold",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "auth",
"id": "579b695decfa11012711875d"
},
"data": {
"hold" : {
"code" : "account_issue_no_service_account",
"text" : "Please login and add your service account."
},
"company" : {
"_id" : "55942f330cfcfd6c4ed529d8",
"name" : "Geico"
}
}
}
}
}
When an auth receives a hold that prevents access to the account data.
Attribute | Description |
---|---|
type |
auth.hold |
payload.resource.id |
The ID of the auth that was put on hold. |
payload.resource.type |
The type of resource referred to by the resource.id. Value: auth . |
payload.data.hold |
The hold placed on the account. |
payload.data.company |
The company object linked to this resource. |
Auth needs resync
Example
auth.needs-resync
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "auth.needs-resync",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "auth",
"id": "579b695decfa110127118752"
},
"data": {
"company" : {
"_id" : "55942f330cfcfd6c4ed529d8",
"name" : "Geico"
}
}
}
}
}
When an auth requires the client to re-verify credentials.
Attribute | Description |
---|---|
type |
auth.needs-resync |
payload.resource.id |
The ID of the auth that needs to be resynced. |
payload.resource.type |
The type of resource referred to by the resource.id. Value: auth . |
payload.data.company |
The company object linked to this resource. |
Bill created
Example
bill.created
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "bill.created",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "bill",
"id": "579b695decfa11012711875d"
},
"data": {
"auth": {
"_id": "579b695decea110719b1874d",
"status": {
"type": "verified"
},
"company": {
"_id": "579b695decea110719b1874d",
"name": "XYZ Electric",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/7242937ba29042cce61a8e4745269fce.png",
"background": false
}
}
}
}
}
}
}
When a bill is found on an associated auth.
Attribute | Description |
---|---|
type |
bill.created |
payload.data.auth |
The auth object linked to the bill. |
Bill upcoming
Example
bill.upcoming
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "bill.upcoming",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "bill",
"id": "579b695decfa11012711875d"
},
"data": {
"company": {
"name": "Netflix"
},
"bill": {
"balance": "52.11",
"dueDate": "2019-03-28 17:00:00.000"
}
}
}
}
}
When an upcoming bill is due in the next two days.
Attribute | Description |
---|---|
type |
bill.upcoming |
payload.data.company |
The company object linked to this resource. |
payload.data.bill |
Object containing the current bill balance and due date. |
Bill update
Example
bill.update
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "bill.update",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "bill",
"id": "579b695decfa11012711875d"
},
"data": {
"company": {
"name": "Netflix"
},
"bill": {
"balance": {
"previous": "25.21",
"current": "52.11"
},
"dueDate": {
"current": "2019-03-28 17:00:00.000"
}
}
}
}
}
}
When a bill's outstanding balance changes. Note that the payload.data.previous
value may not always be available. For instance, when the system first aggregates bill data, the previous bill balance may not have been known. Also note that when the payload.data.previous.balance
is 0.00
and there is a new current balance, this means that a new bill was issued by the company's system.
Attribute | Description |
---|---|
type |
bill.update |
payload.data.company |
The company object linked to this resource. |
payload.data.bill |
Object containing the names of the bill attributes that have changed and their previous values as well as the current bill due date. |
Bill scheduled payment notice
Example
bill.scheduled-payment-notice
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "bill.scheduled-payment-notice",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "bill",
"id": "579b695decfa11012711875d"
},
"data": {
"company": {
"name": "XYZ Electric"
},
"bill": {
"dueDate": {
"previous": "2019-03-20 17:00:00.000",
"current": "2019-03-28 17:00:00.000"
}
}
}
}
}
}
When the due date changes after a bill payment has been scheduled.
Attribute | Description |
---|---|
type |
bill.scheduled-payment-notice |
payload.data.company |
The company object linked to this resource. |
payload.data.bill |
The bill object containing attributes that have changed with their current and previous values, if available. |
Bill payment sent
Example
bill.payment.sent
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "bill.payment.sent",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "bill",
"id": "579b695decfa11012711875d"
},
"data": {
"company": {
"name": "Netflix"
},
"amount": "25.21",
"paymentMethod":{
"_id": "5c5b2ed67d94870391c30b33",
"type": "card",
"name": "Johnny Appleseed",
"status": "verified",
"default":true,
"card":{
"number": "XXXX1111",
"bin": "41111111",
"brand": "visa",
"type": "credit",
"expDate": "2021-06-01T12:00:00.000Z",
"cancelled":false
},
"assignedBills":[
"5c5b2eba5ddb120427c41ba3"
]
},
"surcharge": {
"type": "debit",
"rate": "2.50"
}
}
}
}
}
When a payment is made towards a bill's outstanding balance. Note that the payload.data.surcharge
may not be available when a company does not require it.
Attribute | Description |
---|---|
type |
bill.payment.sent |
payload.data.company |
The company object linked to this resource. |
payload.data.paymentMethod |
The payment method object linked to the payment. |
payload.data.amount |
The amount sent to the company. |
payload.data.surcharge |
The surcharge required by the company to process the payment. |
payload.data.surcharge.type |
The type of surcharge required. Possible values are credit , debit , or ach . |
payload.data.surcharge.rate |
The fee amount the company requires to process the payment. |
Bill payment scheduled
Example
bill.payment.scheduled
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "bill.payment.scheduled",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "bill",
"id": "579b695decfa11012711875d"
},
"data": {
"company": {
"name": "XYZ Electric"
},
"paymentMethod": {
"_id": "5c5b2ed67d94870391c30b33",
"type": "card",
"name": "Johnny Appleseed",
"status": "verified",
"default": true,
"card": {
"number": "XXXX1111",
"bin": "41111111",
"brand": "visa",
"type": "credit",
"expDate": "2021-06-01T12:00:00.000Z",
"cancelled": false
},
"assignedBills": [
"5c5b2eba5ddb120427c41ba3"
]
},
"amount": "95.21",
"payDate": "2019-03-28 17:00:00.000",
"surcharge": {
"type": "debit",
"rate": "2.50"
}
}
}
}
}
When a payment is made towards a bill's outstanding balance. Note that the payload.data.surcharge
may not be available when a company does not require it.
Attribute | Description |
---|---|
type |
bill.payment.scheduled |
payload.data.company |
The company object linked to this resource. |
payload.data.amount |
The amount sent to the company. |
payload.data.payDate |
The date the bill should be paid. |
payload.data.paymentMethod |
The payment method object linked to the payment. |
payload.data.surcharge |
The surcharge required by the company to process the payment. |
payload.data.surcharge.type |
The type of surcharge required. Possible values are credit , debit , or ach . |
payload.data.surcharge.rate |
The fee amount the company requires to process the payment. |
Bill payment cancelled
Example
bill.payment.cancelled
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "bill.payment.cancelled",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "bill",
"id": "579b695decfa11012711875d"
},
"data": {
"company": {
"name": "XYZ Electric"
},
"paymentMethod": {
"_id": "5c5b2ed67d94870391c30b33",
"type": "card",
"name": "Johnny Appleseed",
"status": "verified",
"default": true,
"card": {
"number": "XXXX1111",
"bin": "41111111",
"brand": "visa",
"type": "credit",
"expDate": "2021-06-01T12:00:00.000Z",
"cancelled": false
},
"assignedBills": [
"5c5b2eba5ddb120427c41ba3"
]
},
"bill": {
"dueDate": {
"current": "2019-03-28 17:00:00.000"
},
"amount": {
"current": "40.00"
}
},
"trigger": "client"
}
}
}
}
When a scheduled payment is cancelled.
Attribute | Description |
---|---|
type |
bill.payment.cancelled |
payload.data.company |
The company object linked to this resource. |
payload.data.paymentMethod |
The payment method object linked to the payment. |
payload.data.bill |
Object containing the names of the bill attributes that have changed and their previous values if available. |
payload.data.trigger |
The entity that triggered this event. Possible values are client , system . |
Bill payment failed
Example
bill.payment.failed
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "bill.payment.failed",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "bill",
"id": "579b695decfa11012711875d"
},
"data": {
"amount": "25.21",
"company": {
"name": "Netflix"
},
"paymentMethod":{
"_id": "5c5b2ed67d94870391c30b33",
"type": "card",
"name": "Johnny Appleseed",
"status": "verified",
"default":true,
"card":{
"number": "XXXX1111",
"bin": "41111111",
"brand": "visa",
"type": "credit",
"expDate": "2021-06-01T12:00:00.000Z",
"cancelled":false
},
"assignedBills":[
"5c5b2eba5ddb120427c41ba3"
]
}
}
}
}
}
When a payment is unsuccessful.
Attribute | Description |
---|---|
type |
bill.payment.failed |
payload.data.company |
The company linked to this resource. |
payload.data.paymentMethod |
The payment method linked to the payment. |
payload.data.amount |
The amount of the unsuccesful payment. |
Swap success
Example
swap.success
Event
{
"event": {
"_id": "580e3e11dec21e861b5a3719",
"type": "swap.success",
"created": "2016-04-20T16:51:12Z",
"clientId": "579b695decfa110127118752",
"partnerId": "55942f330cfcfd6c4ed529d9",
"identifier": "example-id-123",
"payload": {
"resource": {
"type": "swap",
"id": "5ce443c56013221715960365"
},
"data": {
"clientId": "5c7c01c11f915c41f89de856",
"company": {
"_id": "5bd885fccd274b4324a21f57",
"name": "Test Merchant",
"status": "operational",
"logo": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/1a49a63fa87749b3abdf74c2ee9deb36.png",
"background": false,
"svg": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/968e40f95dd9a0e85cbae10fb221059b.svg",
"color": "06C580"
},
"symbol": {
"url": "https://s3.amazonaws.com/app-assets.unbill.io-primary/uploads/utility-provider-logos/2533c1ac55b047c770085cc24e3d1e85.svg",
"color": "06C580"
}
},
"auth": {
"urls": {
"login": "https://biller-direct.q2open.io",
"signup": "https://www.q2ebanking.com/",
"forgotUser": "https://www.q2ebanking.com/",
"forgotPassword": "https://www.q2ebanking.com/"
},
"loginFields": [
{
"placeholder": "Username",
"formType": "text",
"name": "username",
"label": "Username"
},
{
"placeholder": "Password",
"formType": "password",
"name": "password",
"label": "Password"
}
]
},
"userPresenceRequired": false,
"supportedItems": ["auth", "bill", "swap", "payment"]
},
"paymentMethod": {
"_id": "5c8dc5ea03bb895bc3868a28",
"type": "card",
"name": "John Doe",
"status": "verified",
"card": {
"number": "XXXX4444",
"bin": "11111111",
"brand": "visa",
"type": "credit",
"expDate": "2023-06-01T12:00:00.000Z",
"cancelled": false
}
}
}
},
"_id": "5ceec9223b461830de21b024",
"type": "swap.success",
"clientId": "5c7c01c11f915c41f89de856",
"partnerId": "58f528495d3f18631d04c4a1",
"identifier": "412255",
"created": "2019-05-29T18:02:10.804Z",
"__v": 0
}
}
When a swap is successful.
Attribute | Description |
---|---|
type |
swap.success |
payload.resource.id |
The ID of the swap that was successful. |
payload.resource.type |
The type of resource referred to by the resource.id. Value: swap . |
payload.data.clientId |
The clientId linked to the swap. |
payload.data.company |
The company object related to the swap. |
payload.data.paymentMethod |
The payment method object linked to the swap. |
Webhook security
The Biller Direct/Cardswap system can also apply additional security measures to webhook events sent to partners. These measures include oauth authentication, payload encryption and request signing.
OAuth Authentication
The webhook can be set up to retrieve a
client credentials token
from an OAuth endpoint provided by the partner. The OAuth response must follow the standard client credentials format.
This token will be cached in Biller Direct/Cardswap until its expiration nears and at that point another
token will be requested from the endpoint. The resulting token will be passed as a Bearer
token in
the Authorization
header along with the event payload.
Setup in Nexus
- In the Nexus portal
Settings
view, click theEdit
button on the desired webhook. - Expand the
OAuth
section of the webhook properties. - Enable OAuth support by toggling the checkbox.
- Add in the
OAuth URL
provided by the partner. - Add in any
OAuth Payload
that should be included in the OAuth request in URL format.
Example Encrypted Request
HTTP/1.1 200 OK
Content-Type: application/jose+json
eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.
UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm
1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKxGHZ7Pc
HALUzoOegEI-8E66jX2E4zyJKx-YxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIF
NPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPhcCdZ6XDP0_F8
rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTP-cFPgwCp6X-nZZd9OHBv
-B3oWh2TbqmScqXMR4gp_A.
AxY8DCtDaGlsbGljb3RoZQ.
KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY.
9hH0vgRfYgPnAHOd8stkvw
Payload Encryption
Event messages to webhook endpoints may be encrypted using standards-based JWE (JSON Web Encryption) compact formatting. In the case of JWE formatting the key ID (kid) is stored in the JWE header included in the encoded payload.
JWE Settings
- Format -
compact
- The format of the JWE itself. Compact is an efficient encoded string. - Content Algorithm (enc) -
A256GCM
- The symmetric algorithm used to encrypt the actual content. - Key Wrapping Algorithm (alg) -
RSA-OAEP
- The asymmetric algorithm used to encrypt the symmetric key.
Setup in Nexus
- In the Nexus portal
Settings
view, click theEdit
button on the desired webhook. - Expand the
Payload Encryption
section of the webhook properties. - Enable encryption support by toggling the checkbox.
- Add in the
Public Key URL
provided by the partner. - Add in any
Request Headers
that should be included with the request in JSON format.
Example
Signature
JWT Headers
{
"typ": "JWT",
"alg": "RS256",
"kid": "key_id_3",
"x5t": "Mx3Fyhwerew23wfs"
}
Example
Signature
JWT Claims
{
"aud": "audience.example.com",
"iss": "example issuer",
"exp": 1579754951
}
RSA Request Signing
Webhook requests may include a request signature for verification. In the case of webhooks, a signed
JWT (JSON Web Token) will be created and sent in a header of the webhook event request. The header defaults to signature
but this can be customized to whichever header the partner would like.
RSA Signing Keys
RSA request signing key-pairs can be created in the Nexus portal Settings
view, and the public key can be copied.
- A maximum of 2 keys can be created for key rotation purposes.
- Public keys are copied in PCKS #8 format.
- Public keys can also be retrieved from the partner public key API.
- The oldest key of the two will be used to create the request signature
Request Signature Setup
- In the Nexus portal
Settings
view, click theEdit
button on the desired webhook. - Expand the
Request Signature
section of the webhook properties. - Enable signature support by toggling the checkbox.
- All parameters for the request signature are optional.
Token Issuer
- Specifies theiss
value to be included with the JWTToken Audience
- Specifies theaud
value to be included with the JWTSignature Header
- Specifies a request header other thansignature
to use for the signature JWT