Initiate a Card Present Authorization
This page covers the support of separate auth from capture on the Braintree In-Person solution from a card present perspective.
Feature Overview
For some use cases where a capture delay is required (ex: endless aisle, save the sale, tipping on receipt, hotel check-in), you may need to request an authorization rather than requesting a charge. This gives the API caller complete control over the authorization capture cadence rather than relying on automated Braintree capture logic. Generally, this operates similarly to e-commerce authorization flows, with some important differences.
Initializing the Reader for Authorization
When you're ready to charge a customer, you can create an In-Store Context
by requesting to authorize a card on the reader. In this step, your
application will specify at minimum, the
readerId
,
merchantAccountId
and
transaction.amount
details to initialize the reader for payment acceptance. Note that the
merchantAccountId
is not validated against in the Sandbox
environment; however, this is a required value in the Production
environment for all interactions with the card reader.
Authorizing is similar to charging, except that if the authorization is
successful, Braintree will NOT capture the transaction. It would be up to
the merchant to send a separate capture request using the
transaction.id
to complete the charge.
To provide idempotency on the
requestAuthorize
mutation, you must also include the HTTP header
Idempotency-Key
with a unique value. UUIDv4 is recommended.
For example, if using
curl
to make the request, you would include
--header 'Idempotency-Key: 94c9ea8b-31b0-488e-a231-57e32f0bfd70'
- GraphQL Mutation
- GraphQL Variables
- Sample API Response
mutation RequestAuthorizeFromInStoreReader($input: RequestAuthorizeFromInStoreReaderInput!) {
requestAuthorizeFromInStoreReader(input: $input) {
clientMutationId
id
status
reader {
id
name
status
}
}
}
Checking the Reader Authorization Status
After the reader is initialized for payment, your application must wait
for the customer to interact with it (i.e. insert a test card) and for the
payment attempt to be processed. Your application should use
the node query
to poll on a 2-second interval between responses for the current status of
the payment using the
RequestChargeInStoreContext.id
received at charge initialization and monitor the
RequestAuthorizeInStoreContext.status
field as the transaction
goes through the lifecycle.
When the
RequestAuthorizeInStoreContext.status
changes to "COMPLETE", you will also receive a transaction object
RequestAuthorizeInStoreContext.transaction
in the response.
Save the completed
RequestAuthorizeInStoreContext.transaction.id
in your database for referencing the transaction in subsequent operations
(ie. capture, adjust auth, void, etc...).
All successful test transactions should have a transaction amount value below $2,000 for testing. For more info on using amounts to simulate various transaction outcomes, take a look at Testing Your Integration.
- Query
- Sample API response (successful auth)
{
node(id: "{{last_braintree_instore_context}}") {
... on RequestAuthorizeInStoreContext {
id
status
statusReason
reader {
id
name
status
}
transaction {
id
orderId
status
statusHistory {
... on PaymentStatusEvent {
status
timestamp
terminal
... on AuthorizedEvent {
authorizationExpiresAt
processorResponse {
authorizationId
emvData
message
legacyCode
retrievalReferenceNumber
}
}
... on GatewayRejectedEvent {
gatewayRejectionReason
}
... on FailedEvent {
processorResponse {
retrievalReferenceNumber
emvData
message
legacyCode
}
networkResponse {
message
code
}
}
... on ProcessorDeclinedEvent {
processorResponse {
legacyCode
message
authorizationId
additionalInformation
retrievalReferenceNumber
emvData
}
declineType
networkResponse {
code
message
}
}
}
}
merchantAddress {
company
streetAddress
addressLine1
extendedAddress
addressLine2
locality
adminArea2
region
adminArea1
postalCode
countryCode
phoneNumber
}
amount {
value
currencyIsoCode
}
merchantAccountId
merchantName
createdAt
channel
customFields {
name
value
}
paymentMethodSnapshot {
... on CreditCardDetails {
origin {
details {
... on EmvCardOriginDetails {
applicationPreferredName
applicationIdentifier
terminalId
inputMode
pinVerified
}
}
}
brandCode
last4
bin
expirationMonth
expirationYear
cardholderName
binData {
issuingBank
countryOfIssuance
prepaid
healthcare
debit
commercial
}
}
}
}
}
}
}
Capturing funds against an Authorization
To capture the authorized funds, you must use the Capture Transaction mutation within a 24-hour window of the funds being authorized (except for eligible Lodging MCC codes, which have expiry windows of up to 30 days). For a card-present authorization, you are allowed only a single capture attempt. Any remaining authorized funds not captured after the initial capture request will be voided. You may capture a lesser amount than what was authorized or an amount up to the maximum over-capture threshold (subject to eligibility). For merchants processing on MCC codes ineligible for over-capture, the maximum amount allowed for capture is the amount authorized.
Example Capture request
- GraphQL Mutation
- GraphQL Variables
- Sample API Response
mutation CaptureTransaction($input: CaptureTransactionInput!) {
captureTransaction(input: $input) {
transaction {
id
status
}
}
}
Using Incremental Authorizations
For some merchants, for example, those in the Hotels & Hospitality or some other industries, incremental authorizations (aka adjust auth) are an important feature for use cases such as tipping adjustment, hotel room damages, or hotel mini-bar charges, etc... This feature is subject to merchant eligibility based on MCC code, and it is also not supported for AMEX transactions and some other transaction types. This feature leverages the updateTransactionAmount API mutation with Braintree's GraphQL API.
Example Update Transaction Amount request
- GraphQL Mutation
- GraphQL Variables
- Sample API Response
mutation updateTransactionAmount($input: UpdateTransactionAmountInput!) {
updateTransactionAmount(input: $input) {
transaction {
id
status
customer{
email
firstName
lastName
id
}
}
}
}
Using Estimated Auth (Pre-Auth)
Using an estimated authorization or a "pre-auth" can help avoid issuer
rejections and improve authorization rates for scenarios when you may not
know the final charge amount at the time of authorization. Some industries
where this may be common are hotels, vehicle rentals, bars, etc... It is
recommended that you use this feature if you are using incremental auth.
To trigger an estimated authorization you must pass the
paymentInitiator
flag with a value of "ESTIMATED
". See example below:
- GraphQL Mutation
- GraphQL Variables
mutation RequestAuthorizeFromInStoreReader($input: RequestAuthorizeFromInStoreReaderInput!) {
requestAuthorizeFromInStoreReader(input: $input) {
clientMutationId
inStoreContext {
id
status
transaction {
id
orderId
status
customer{
id
}
paymentMethodSnapshot{
__typename
... on CreditCardDetails {
brandCode
bin
last4
cardholderName
expirationMonth
expirationYear
}
}
}
reader {
id
name
status
softwareVersion
}
}
}
}
AMEX Over Capture Rules
MCC codes such as 4821 (Taxi Cabs and Rideshares) and 5812 (Restaurants) are allowed to capture up to 20% more than the authorized amount.
MCC codes such as 7011 (Lodging), 7512/7513/7519 (Vehicle Rentals), as well as Cruise Lines, Grocery merchants, and Retailers are allowed to capture up to 15% more than the authorized amount.
If you have a direct contract with AMEX, you may need to reach out to them to have them configure your account to allow for over-captures.
Important Tips When Integrating Separate Auth from Capture
-
Some MCC codes are allowed to capture more (aka over capture) than the authorized amount (typically used by restaurant merchants for tipping purposes)
-
Some MCC codes are allowed to use incremental authorizations (adjust auth) in order to incrementally increase the auth amount (typically used by Hotel & Hospitality merchants)
-
To enable over-captures or incremental authorizations, your Braintree account must be configured accordingly. Please work with your Solutions Engineer or Integration Engineer to facilitate this
-
Incremental Auth is not supported for AMEX transactions. For some use cases, you may need to perform an over-capture for an AMEX transaction
-
Passing of L2/L3 data is not supported in the authorization request; however, you may pass this data in the separate capture request