JPMorgan
This page provides an overview of the payments methods provided by the JPMorgan adapter in the IXOPAY platform. It also includes a full list of all configuration options available to you when integrating JPMorgan within your payments landscape, as well as an overview of the parameters required when submitting a transaction via IXOPAY's API.
Process low-value ACH direct debits and refunds in the US and Canada via JPMorgan's Treasury Payments API.
Supported featuresβ
Payment methodsβ
The table below lists the payment methods that JPMorgan ACH Direct Debit supports. It also includes the available processing options and the supported transaction types for each of those payment methods.
| Payment method | Processing options | Transaction types |
|---|---|---|
| ACH Direct Debit | Server-to-server Hosted payment page | Debit Refund (full & partial) Register Deregister |
Currenciesβ
USD, CAD
Register transactionsβ
Register stores the submitted bank account details so they can be reused for subsequent transactions. No verification or registration takes place with JPMorgan at this point.
Bank account detailsβ
Debtor (customer) bank account number, routing/ABA number, IBAN, and account type are not read from the customer's IBAN fields. They are supplied in one of two ways:
- Server-to-server β submitted as
extraDataunder thepsp:directDebitTransactionInformation.debtorAccount.*keys documented below. - Hosted payment page β entered by the payer on a page hosted by the gateway (see below).
Hosted payment pageβ
Enable the connector option Collect Bank Details on Hosted Payment Form to let the payer enter their own bank details instead of submitting them with the request. Send a debit or register without an account number and routing number, and the response returns a redirect URL. Send the payer there; once they submit, the payment continues and you receive the result as usual.
The page collects:
| Field | Maps to |
|---|---|
| Account Holder Name | directDebitTransactionInformation.debtor.name |
| Account Number | directDebitTransactionInformation.debtorAccount.accountNumber |
| Account Type | directDebitTransactionInformation.debtorAccount.type.code |
| Routing Number | directDebitTransactionInformation.debtorAgent.financialInstitutionId.aba |
| Bank Name | directDebitTransactionInformation.debtorAgent.financialInstitutionId.name |
| Bank City | directDebitTransactionInformation.debtorAgent.financialInstitutionId.postalAddress.townName |
| Collection Date | requestedCollectionDate |
| Country | directDebitTransactionInformation.debtor.postalAddress.country |
The routing number is checked against the ABA format and checksum before the page is submitted, and the collection date cannot be set earlier than the current processing date on JPMorgan's clock.
Values supplied in the original API request take precedence: if you send customer.billingCountry, for example, the payer's entry is ignored. Any field you do not send is collected from the payer instead.
Required by JPMorganβ
All three of the following must reach the request, or JPMorgan rejects the payment with NARR / INVALID PM VEHICLE. The rejection arrives in the status notification, not in the response to your request.
| Field | Where it comes from |
|---|---|
paymentTypeInformation.localInstrument.code | Local Instrument Code connector option (NACHA SEC code, e.g. CCD for corporate, PPD for consumer) |
directDebitTransactionInformation.debtorAgent.financialInstitutionId.postalAddress.country | Debtor Agent Country connector option |
directDebitTransactionInformation.debtor.postalAddress.country | customer.billingCountry in the request, or the Country field on the hosted page |
The first two are connector configuration and normally need no per-transaction value. The third has no connector fallback and must be supplied per transaction.
Collection dateβ
psp:requestedCollectionDate is the date JPMorgan processes the collection, not the date the money moves. Funds leave the payer one to three clearing business days after the collection is initiated.
- The earliest date you can send is the current date on JPMorgan's processing clock (US Eastern). An earlier date is rejected with
DT01. - Omit the field and the current date is used.
- A date falling on a weekend or a US bank holiday is not rejected β JPMorgan processes it on the next working day.
- Only a date is sent, never a time, so JPMorgan's daily cut-off does not change what you submit. It only affects how soon JPMorgan starts processing.
Mapping to JPMorganβ
This segment provides a comprehensive guide to effectively integrate JPMorgan ACH Direct Debit into your payment procedure. It offers a detailed mapping between the fields of the gateway and corresponding fields on the JPMorgan side.
All extraData keys use the psp: prefix convention. Fields not listed as required can be omitted unless noted.
Parametersβ
Request mappingβ
| Gateway parameter | JPMorgan parameter | Type | Description | Transaction types |
|---|---|---|---|---|
extraData.psp:paymentTypeInformation.categoryPurpose.proprietary | paymentTypeInformation.categoryPurpose.proprietary | optional string? | Category purpose proprietary code | only: Debit |
extraData.psp:chargeBearer | chargeBearer | optional string? | Who bears the transaction charges | |
extraData.psp:requestedCollectionDate | requestedCollectionDate | optional string?Also settable on the hosted page; defaults to the current date | Processing date for the debit (YYYY-MM-DD) β see Collection date. A date in the past is rejected by JPMorgan with DT01 | only: Debit |
extraData.psp:requestedCollectionDate | requestedExecutionDate | optional string?Defaults to today's date | Execution date for the refund (YYYY-MM-DD) | only: Refund |
extraData.psp:paymentTypeInformation.serviceLevelCode | paymentTypeInformation.serviceLevelCode | optional string?Falls back to the Service Level Code config option | Service level code | |
extraData.psp:paymentTypeInformation.localInstrument.code | paymentTypeInformation.localInstrument.code | required stringFalls back to the Local Instrument Code config option | NACHA Standard Entry Class code, e.g. CCD (corporate) or PPD (consumer). JPMorgan rejects the payment without it | |
extraData.psp:paymentTypeInformation.localInstrument.proprietary | paymentTypeInformation.localInstrument.proprietary | optional string? | Local instrument proprietary value | |
extraData.psp:paymentTypeInformation.categoryPurpose.code | paymentTypeInformation.categoryPurpose.code | optional string? | Category purpose code | |
extraData.psp:paymentTypeInformation.sequenceType | paymentTypeInformation.sequenceType | optional string? | Direct debit sequence type (e.g. one-off, recurring) | |
extraData.psp:creditor.name | creditor.name, directDebitTransactionInformation.ultimateCreditor.name | optional string?Falls back to the Creditor Name config option | Creditor legal name | |
extraData.psp:creditor.postalAddress.streetName | creditor.postalAddress.streetName | optional string?Falls back to Creditor Postal Address Street Name config option | ||
extraData.psp:creditor.postalAddress.postCode | creditor.postalAddress.postCode | optional string?Falls back to Creditor Postal Address Postcode config option | ||
extraData.psp:creditor.postalAddress.townName | creditor.postalAddress.townName | optional string?Falls back to Creditor Postal Address Town Name config option | ||
extraData.psp:creditor.postalAddress.countrySubDivision | creditor.postalAddress.countrySubDivision | optional string?Falls back to Creditor Postal Address Country Sub Division config option | ||
extraData.psp:creditor.postalAddress.country | creditor.postalAddress.country | optional string?Falls back to Creditor Postal Address Country config option | ||
extraData.psp:creditor.postalAddress.addressLine | creditor.postalAddress.addressLine | optional string?Falls back to Creditor Postal Address Address Line config option | Sent as a single-element array | |
extraData.psp:creditorAccount.companyId | creditorAccount.companyId | optional string?Falls back to Creditor Account Company Id config option | JPMorgan ACH Company ID | |
extraData.psp:creditorAccount.currency | creditorAccount.currency | optional string?Falls back to Creditor Account Currency Code config option | ||
extraData.psp:creditorAccount.accountNumber | creditorAccount.accountNumber | optional string?Falls back to Creditor Account Number config option | ||
extraData.psp:creditorAccount.iban | creditorAccount.iban | optional string? | Extra-data only, no config fallback | |
extraData.psp:creditorAgent.name | creditorAgent.name | optional string?Falls back to Creditor Agent Name config option | ||
extraData.psp:creditorAgent.clearingSystemCode | creditorAgent.clearingSystemCode | optional string? | ||
extraData.psp:creditorAgent.country | creditorAgent.country | optional string?Falls back to Creditor Agent Country config option | ||
extraData.psp:creditorAgent.bic | creditorAgent.bic | optional string?Falls back to Creditor Agent BIC config option | ||
extraData.psp:creditorAgent.aba | creditorAgent.aba | optional string?Falls back to Creditor Agent ABA config option | ||
extraData.psp:creditorAgent.memberId | creditorAgent.memberId | optional string?Falls back to Creditor Agent Member Id config option | ||
extraData.psp:creditorSchemeId.privateId.id | creditorSchemeId.privateId.id | optional string? | ||
extraData.psp:creditorSchemeId.privateId.schemeName.proprietary | creditorSchemeId.privateId.schemeName.proprietary | optional string? | ||
extraData.psp:directDebitTransactionInformation.remittanceInformation.unstructured | directDebitTransactionInformation.remittanceInformation.unstructured | optional string? | Sent as a single-element array | |
extraData.psp:directDebitTransactionInformation.regulatoryReporting | directDebitTransactionInformation.regulatoryReporting | optional mixed? | Passed through as-is, no structured mapping | |
extraData.psp:directDebitTransactionInformation.ultimateCreditor.postalAddress.{streetName,buildingNumber,postCode,townName,countrySubDivision,country,addressLine} | directDebitTransactionInformation.ultimateCreditor.postalAddress.{streetName,buildingNumber,postCode,townName,countrySubDivision,country,addressLine} | optional string?(all but buildingNumber) fall back to the matching Creditor Postal Address * config option | ||
extraData.psp:directDebitTransactionInformation.ultimateCreditor.organizationId.bicOrBei | directDebitTransactionInformation.ultimateCreditor.organizationId.bicOrBei | optional string? | ||
extraData.psp:directDebitTransactionInformation.ultimateCreditor.organizationId.other.{id,schemeName.code,schemeName.proprietary,issuer} | directDebitTransactionInformation.ultimateCreditor.organizationId.other.{id,schemeName.code,schemeName.proprietary,issuer} | optional string? | ||
extraData.psp:directDebitTransactionInformation.ultimateCreditor.privateId.dateAndPlaceOfBirth.{birthDate,cityOfBirth,countryOfBirth} | directDebitTransactionInformation.ultimateCreditor.privateId.dateAndPlaceOfBirth.{birthDate,cityOfBirth,countryOfBirth} | optional string? | ||
extraData.psp:directDebitTransactionInformation.ultimateCreditor.privateId.other.{id,schemeName.code,schemeName.proprietary,issuer} | directDebitTransactionInformation.ultimateCreditor.privateId.other.{id,schemeName.code,schemeName.proprietary,issuer} | optional string? | ||
extraData.psp:directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.mandateId | directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.mandateId | optional string? | SEPA-style mandate ID; this adapter does not create or store mandates itself | |
extraData.psp:directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.dateOfSignature | directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.dateOfSignature | optional string? | ||
extraData.psp:directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.amendmentIndicator | directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.amendmentIndicator | optional boolean? | ||
extraData.psp:directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.amendmentInformationDetails.originalMandateId | directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.amendmentInformationDetails.originalMandateId | optional string? | ||
extraData.psp:directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.amendmentInformationDetails.originalCreditorSchemeId.name | directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.amendmentInformationDetails.originalCreditorSchemeId.name | optional string? | ||
extraData.psp:directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.amendmentInformationDetails.originalCreditorSchemeId.privateId.id | directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.amendmentInformationDetails.originalCreditorSchemeId.privateId.id | optional string? | ||
extraData.psp:directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.amendmentInformationDetails.originalCreditorSchemeId.privateId.schemeName.proprietary | directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.amendmentInformationDetails.originalCreditorSchemeId.privateId.schemeName.proprietary | optional string? | ||
extraData.psp:directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.amendmentInformationDetails.originalDebtorAccount.otherId | directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.amendmentInformationDetails.originalDebtorAccount.otherId | optional string? | ||
extraData.psp:directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.electronicSignature | directDebitTransactionInformation.directDebitTransaction.mandateRelatedInformation.electronicSignature | optional string? | ||
extraData.psp:directDebitTransactionInformation.debtorAgent.financialInstitutionId.aba | directDebitTransactionInformation.debtorAgent.financialInstitutionId.aba | required string | Debtor bank routing/ABA number; also used as the routing number fallback returned in AchData on registration | |
extraData.psp:directDebitTransactionInformation.debtorAgent.financialInstitutionId.name | directDebitTransactionInformation.debtorAgent.financialInstitutionId.name | optional string?Also set by the hosted page | Name of the debtor's bank. JPMorgan asks for it alongside the routing number, so supply it on the API path too | |
extraData.psp:directDebitTransactionInformation.debtorAgent.financialInstitutionId.{bic,clearingSystemCode,otherId,memberId} | directDebitTransactionInformation.debtorAgent.financialInstitutionId.{bic,clearingSystemCode,otherId,memberId} | optional string? | ||
extraData.psp:directDebitTransactionInformation.debtorAgent.financialInstitutionId.postalAddress.country | directDebitTransactionInformation.debtorAgent.financialInstitutionId.postalAddress.country | required stringFalls back to the Debtor Agent Country config option | Country of the debtor's bank (US for US ACH). JPMorgan rejects the payment without it | |
extraData.psp:directDebitTransactionInformation.debtorAgent.financialInstitutionId.postalAddress.townName | directDebitTransactionInformation.debtorAgent.financialInstitutionId.postalAddress.townName | optional string?Also set by the hosted page | Town of the debtor's bank. JPMorgan asks for it alongside the bank name, so supply it on the API path too | |
extraData.psp:directDebitTransactionInformation.debtorAgent.financialInstitutionId.postalAddress.{streetName,buildingNumber,postCode,countrySubDivision,addressLine} | directDebitTransactionInformation.debtorAgent.financialInstitutionId.postalAddress.{streetName,buildingNumber,postCode,countrySubDivision,addressLine} | optional string? | ||
extraData.psp:directDebitTransactionInformation.debtor.name(else from Customer object) getBankAccountOwner() or getFullName() | directDebitTransactionInformation.debtor.name | required string | Name on the debtor's bank account. Supply the psp: key when the account holder differs from the customer name; also set by the hosted page | |
(from Customer object, extraData) psp:directDebitTransactionInformation.debtor.{department,subDepartment,buildingNumber,townName,countrySubDivision,contactDetails.other} | directDebitTransactionInformation.debtor.postalAddress.{department,subDepartment,buildingNumber,townName,countrySubDivision} / directDebitTransactionInformation.debtor.contactDetails.other | optional string?Stored on the customer's extraData, not the transaction's | ||
(from Customer object) getBillingCountry() | directDebitTransactionInformation.debtor.postalAddress.country | required string | Send as customer.billingCountry, or let the payer select it on the hosted page. No connector fallback β JPMorgan rejects the payment without it | |
(from Customer object) getBillingAddress1() / getBillingPostcode() | directDebitTransactionInformation.debtor.postalAddress.streetName / directDebitTransactionInformation.debtor.postalAddress.postCode | optional string? | ||
(from Customer object) getBic() | directDebitTransactionInformation.debtor.organizationId.bicOrBei | optional string? | ||
(from Customer object) getBirthDate() | directDebitTransactionInformation.debtor.privateId.dateAndPlaceOfBirth.birthDate | optional string? | ||
(from Customer object) getBillingPhone() / getEmail() | directDebitTransactionInformation.debtor.contactDetails.phoneNumber / directDebitTransactionInformation.debtor.contactDetails.emailAddress | optional string? | ||
extraData.psp:directDebitTransactionInformation.debtorAccount.type.{code,proprietary} | directDebitTransactionInformation.debtorAccount.type.{code,proprietary} | optional string?Send on the transaction's or the customer's extraData; also set by the hosted page | Checking or savings. Determines the NACHA transaction code, so send it whenever the account is not a checking account | |
extraData.psp:directDebitTransactionInformation.debtorAccount.currency | directDebitTransactionInformation.debtorAccount.currency | optional string?Falls back to the transaction currency | ||
extraData.psp:directDebitTransactionInformation.debtorAccount.accountNumber | directDebitTransactionInformation.debtorAccount.accountNumber | required string | Debtor bank account number | |
extraData.psp:directDebitTransactionInformation.debtorAccount.iban | directDebitTransactionInformation.debtorAccount.iban | optional string? |
Response mappingβ
A successful response to a debit does not mean the payment was accepted β JPMorgan only confirms that it received the instruction, and returns PMT-C001 / SUCCESS in the processor response fields. The transaction stays pending until JPMorgan sends its status notification, typically 10 to 20 minutes later.
Wait for the postback before treating an ACH debit as paid.
| Gateway parameter | JPMorgan parameter | Type | Description | Transaction types |
|---|---|---|---|---|
secondAdapterTxId | endToEndId | string | End-to-end transaction identifier | |
processorId | jpmcPmtRefId | string | JPMorgan payment reference ID | |
processorResponseCode | processingInfo.statusCode | string | Processor status code | |
processorResponseMessage | processingInfo.statusText | string | Processor status text |
On registration (Register, or a Debit submitted "with register"), the following ACH bank data is stored for later reuse:
| AchData field | Source |
|---|---|
accountNumber | psp:directDebitTransactionInformation.debtorAccount.accountNumber |
routingNumber | debtorAgent.financialInstitutionId.aba, else .memberId, else .clearingSystemCode |
accountType | debtorAccount.type.code, else .type.proprietary, else empty string |
accountHolder / accountHolderType | Customer's company name (company) or full name |
Callback mappingβ
JPMorgan sends an asynchronous callback with a JSON body containing a transactionData array (or single object). A single callback can carry updates for up to 50 payments. Each entry is mapped as follows:
JPMorgan paymentStatus | Gateway result |
|---|---|
HOLD | Pending postback |
ACCEPTED, CLEARED, COMPLETED | OK |
REJECTED, RETURNED | Error (mapped via the error code table below, using processingInfo.statusCode/.statusText) |
| (any other value) | Ignored |
| Gateway parameter | JPMorgan parameter |
|---|---|
adapterTxId, processorId | jpmcPmtRefId |
secondAdapterTxId | endToEndId |
Error codesβ
| JPMorgan error code | Gateway error code | JPMorgan error message |
|---|---|---|
PMT-E005 | INVALID_REQUEST_DATA | EndToEndId field is required |
PMT-E006 | INVALID_REQUEST_DATA | EndToEndId is not in correct format |
PMT-E010 | DUPLICATE_TRANSACTION_ID | endToEndId must be unique |
PMT-E011 | INVALID_REQUEST_DATA | instructedAmount or equivalentAmount is required with amount and currency fields |
PMT-E009 | INVALID_REQUEST_DATA | instructedAmount field is required |
PMT-E012 | INVALID_REQUEST_DATA | amount field is required |
PMT-E013 | INVALID_REQUEST_DATA | currency field is required |
PMT-E007, GCA-023 | INVALID_REQUEST_DATA | Please re-send request in valid format |
GCA-029 | INCORRECT_PAYMENT_INFO | The requested debit account was not found |
GCA-042 | INVALID_REQUEST_DATA | creditorAccount must NOT be provided with iban AND accountNumber |
GCA-044 | INVALID_REQUEST_DATA | When creditorAccount is provided with iban, creditorAgent must NOT be provided with abaNumber |
GCA-046 | INVALID_REQUEST_DATA | creditorAccount must be provided with iban or accountNumber |
GCA-048 | INVALID_REQUEST_DATA | When creditorAccount is provided with accountNumber, bic or aba is required; when provided with iban, bic is required |
GCA-050 | INVALID_REQUEST_DATA | creditorAgent must NOT be provided with bic AND abaNumber |
GCA-051 | INVALID_CONFIGURATION | ACH Company id and Account combination was not found |
GCA-056 | INVALID_REQUEST_DATA | bic must be provided with accountNumber |
GCA-055 | INVALID_CONFIGURATION | ACH Company id was not provided |
GCA-058 | INVALID_REQUEST_DATA | country is required in the creditorAgent |
GCA-060 | INVALID_CONFIGURATION | serviceLevelCode value is invalid |
GCA-001, GCA-003 | NOT_ALLOWED | Unauthorized Access |
GCA-030 | PROCESSING_ERROR | Access API Processing Error |
GCA-099 | TEMPORARY_UNAVAILABLE | System is Unavailable |
AC01 | INCORRECT_PAYMENT_INFO | Incorrect Account Number |
AC04 | ACCOUNT_CLOSED_EXTERNALLY | Closed Account Number |
AC06 | ACCOUNT_CLOSED_EXTERNALLY | Blocked Account |
AG01 | NOT_ALLOWED | Transaction Forbidden |
AG02 | INVALID_REQUEST_DATA | Invalid Bank Operation Code |
AG03 | NOT_ALLOWED | Transaction Not Supported |
AG07 | TRANSACTION_DECLINED | Unsuccessful Direct Debit |
AM04 | INSUFFICIENT_FUNDS | Insufficient Funds |
AM05 | DUPLICATE_TRANSACTION_ID | Duplication |
AM07 | TRANSACTION_DECLINED | Blocked Amount |
AM12 | INVALID_REQUEST_DATA | Invalid Amount |
BE01 | CUSTOMER_DATA_INVALID | Inconsistent with End Customer |
BE06 | CUSTOMER_DATA_INVALID | Unknown End Customer |
BE15 | CUSTOMER_DATA_INVALID | Invalid Identification Code |
DS02 | TRANSACTION_CANCELLED | Order Cancelled |
DT01 | INVALID_REQUEST_DATA | Invalid date |
ED05 | PROCESSING_ERROR | Settlement Failed |
FF01, FF02 | INVALID_XML | Syntax Error |
FF09 | INVALID_REQUEST_DATA | Invalid Cheque Number |
MD05 | TRANSACTION_DECLINED | Collection Not Due |
MD07 | ACCOUNT_CLOSED_EXTERNALLY | End Customer Deceased |
RC01 | INCORRECT_PAYMENT_INFO | Bank Identifier Incorrect |
RC02 | INCORRECT_PAYMENT_INFO | Invalid Bank Identifier |
RC04 | INCORRECT_PAYMENT_INFO | Invalid Creditor Bank Identifier |
RC08 | INCORRECT_PAYMENT_INFO | Invalid Clearing System Member Identifier |
RR01 | INVALID_REQUEST_DATA | Missing Debtor Account or Identification |
RR04 | TRANSACTION_DECLINED | Regulatory Reason |
RR07 | INVALID_REQUEST_DATA | Remittance Information Invalid |
NARR | UNKNOWN | JPMorgan's free-text reason is returned as the error message, e.g. INVALID PM VEHICLE |
0000, (unrecognized) | UNKNOWN | JPMorgan's own message is returned where one is supplied |
Testingβ
JPMorgan ACH Direct Debit uses JPMorgan's QAF sandbox environment when the connector is in test mode. Refer to JPMorgan's own ACH Direct Debits API documentation for sandbox credentials and test scenarios.