Skip to main content

Migrate to the Consolidated Payment Mutations

new consolidated payment mutations

Highnote has released new consolidated payment mutations. Existing mutations are deprecated (not removed). Please migrate as you touch each call site.

What changed

Highnote's acquiring credential-specific payment mutations are deprecated.

  • One mutation per verb: authorize and charge accept any credential; reverse needs none.
  • One shape: input and response are the same for every credential; only the credential member changes.
  • No new mutations to adopt: new credential types arrive as a new member on the same call.
  • Reversals you can find: full and partial reversals are both under the network name.

Mutation mapping table

Replace each call in your integration with the consolidated mutation that performs the same action:

Legacy mutationReplacement
authorizePaymentCardauthorizePaymentTransaction
authorizeNetworkTokenauthorizePaymentTransaction
authorizePaymentMethodTokenauthorizePaymentTransaction
chargePaymentCardchargePaymentTransaction
chargeNetworkTokenchargePaymentTransaction
chargePaymentMethodTokenchargePaymentTransaction
cancelPaymentTransactionreversePaymentTransaction

One verb, any credential

Until now, the mutation you called depended on what you were charging: a payment card, a network token, and a payment method token each had their own authorize mutation and their own charge mutation.

The credential is now data rather than surface area. It moves into a single credential input that carries exactly one of paymentCard, networkToken, or paymentMethodToken. Amount, payment initiator, idempotency key, and merchant details stay at the top level of the input and are the same whichever credential you send.

Two things follow. Your integration calls the same mutation and handles the same response no matter which credential it presents. And when Highnote supports a new credential type, it arrives as a new member of credential rather than as a new mutation for you to adopt.

Clearer name for reversals

The mutation cancelPaymentTransaction did more than its name suggested. Passing its optional amount performed a partial reversal, and released part of a hold instead of ending the authorization, which is what you need when a final amount comes in below your original estimate. That behavior was reachable only if you already knew it was there.

The mutation reversePaymentTransaction is the same operation under the name the card networks use. Full and partial reversals both live on it, and amount keeps its delta semantics. It is the amount to release, not the new authorization total.

The migration is mechanical. Move the credential under the credential input and pick the member that matches its type; cardHolder and externalCredentialOnFile move inside that member, and every other field stays where it is. The sections below map each legacy mutation to its consolidated call, and Field changes gives the complete field-by-field mapping.

Authorize payment transaction

authorizePaymentTransaction replaces the three credential-specific authorize mutations.

The mutation authorizePaymentTransaction authorizes a payment for later capture. Place a hold on the cardholder's funds now, then capture with capturePaymentTransaction or release the hold with reversePaymentTransaction.

Legacy mutationConsolidated call
authorizePaymentCardauthorizePaymentTransaction(input: { credential: { paymentCard: … } })
authorizeNetworkTokenauthorizePaymentTransaction(input: { credential: { networkToken: … } })
authorizePaymentMethodTokenauthorizePaymentTransaction(input: { credential: { paymentMethodToken: … } })

The following variables show the same payment card authorization before and after migration. The paymentCard details move under credential, and cardHolder moves inside the credential member. Every other field stays where it was.

Legacy — authorizePaymentCard variables
{
"input": {
"paymentCard": {
"cardNumber": "4000000000000002",
"expiryYear": "31",
"expiryMonth": "12",
"securityCode": "111"
},
"cardHolder": {
"billingAddress": {
"streetAddress": "1234 Visa Street",
"countryCodeAlpha3": "USA",
"extendedAddress": "extended-address",
"locality": "Visa",
"region": "California",
"postalCode": "12345"
}
},
"merchantAcceptorId": "<MERCHANT_ACCEPTOR_ID>",
"amount": {
"value": 1000,
"currencyCode": "USD"
},
"idempotencyKey": "UUID_v4",
"paymentInitiator": "CUSTOMER_INITIATED_VIA_WEB"
}
}
Consolidated — authorizePaymentTransaction variables
{
"input": {
"credential": {
"paymentCard": {
"cardNumber": "4000000000000002",
"expiryYear": "31",
"expiryMonth": "12",
"securityCode": "111",
"cardHolder": {
"billingAddress": {
"streetAddress": "1234 Visa Street",
"countryCodeAlpha3": "USA",
"extendedAddress": "extended-address",
"locality": "Visa",
"region": "California",
"postalCode": "12345"
}
}
}
},
"merchantAcceptorId": "<MERCHANT_ACCEPTOR_ID>",
"amount": {
"value": 1000,
"currencyCode": "USD"
},
"idempotencyKey": "UUID_v4",
"paymentInitiator": "CUSTOMER_INITIATED_VIA_WEB"
}
}

Charge payment transaction

chargePaymentTransaction replaces the three credential-specific charge mutations.

The mutation chargePaymentTransaction authorizes and captures a payment in a single round trip and mirrors authorizePaymentTransaction. The input shape is the same, including the same credential choice of payment card, network token, or payment method token. Apply the same change as for authorize by moving the credential under credential and leave the rest of the input unchanged.

Legacy mutationConsolidated call
chargePaymentCardchargePaymentTransaction(input: { credential: { paymentCard: … } })
chargeNetworkTokenchargePaymentTransaction(input: { credential: { networkToken: … } })
chargePaymentMethodTokenchargePaymentTransaction(input: { credential: { paymentMethodToken: … } })

Reverse payment transaction

reversePaymentTransaction is a one-to-one rename of cancelPaymentTransaction.

The mutation reversePaymentTransaction has the same input fields, same behavior, same events as cancelPaymentTransaction. No credential is involved, so the input is unchanged.

Legacy mutationConsolidated call
cancelPaymentTransactionreversePaymentTransaction(input)

The amount field keeps its delta semantics. It is the amount to release back to the cardholder, not the new authorization total.

To reverse the full remaining authorization omit amount. When you supply amount, it must not exceed the remaining authorized amount.

Reversal amount

Reversal amount cannot exceed the remaining authorization. If the amount to reverse exceeds the outstanding authorized amount, the mutation returns a UserError with code REVERSAL_AMOUNT_GREATER_REMAINING_AUTHORIZED_AMOUNT and an errorPath locating the offending amount. Nothing is sent to the network.

Omitting amount performs a full reversal and is never subject to this check.

The following variables attempt to reverse 13.00 USD against an authorization with only 10.00 USD outstanding:

Variables
{
"input": {
"paymentTransactionId": "<PAYMENT_TRANSACTION_ID>",
"amount": {
"value": 1300,
"currencyCode": "USD"
},
"idempotencyKey": "UUID_v4"
}
}
Response
{
"data": {
"reversePaymentTransaction": {
"__typename": "UserError",
"errors": [
{
"code": "REVERSAL_AMOUNT_GREATER_REMAINING_AUTHORIZED_AMOUNT",
"description": "Requested reversal amount is greater than remaining authorized amount",
"errorPath": ["input", "amount"]
}
]
}
}
}

Field changes

Most input fields carry over unchanged. The following table shows where each legacy input field lands in the consolidated inputs, starting with the fields that carry over unchanged:

FieldChange
amount, paymentInitiator, idempotencyKey, merchantAcceptorId, merchantDescriptor, installmentPaymentUnchanged. Same names, same position at the top level of the input.
cardHolderRelocated. Moves inside credential.paymentCard or credential.networkToken.
externalCredentialOnFileRelocated. Moves inside every credential member.
paymentCard, networkTokenRelocated. Becomes the credential.paymentCard or credential.networkToken member — see the mapping tables above.
paymentMethodTokenIdRelocated. Becomes credential.paymentMethodToken.id.
contractIdNot carried over. Already superseded by merchantAcceptorId.

Provide exactly one credential

The credential field must contain exactly one member. If you set zero members or more than one, the request is rejected before any processing occurs, and the failure is returned as a top-level GraphQL validation error rather than in data.

Business-rule rejections, such as a reversal amount that exceeds the remaining authorization, instead return a UserError in data. Populate a single credential member per request.

Reversing vs. increasing an authorization

The reversePaymentTransaction mutation only decreases an authorization. It releases held funds back to the cardholder.

To increase the authorized amount on an existing payment transaction, use incrementalAuthorizePaymentTransaction, which is unaffected by this consolidation.

See Incremental Authorization for details.

Next steps

For runnable, interactive examples of each consolidated mutation, see Online Payments.