Pre-Authorization & Capture

In the first step, the pre-authorization request is made, reserving the specified amount. This ensures that the customer has sufficient funds and that the payment method is valid. However, the funds are not transferred to the merchant at this stage.

In the second step, the capture request is executed to finalize the payment. The pre-authorized amount is then debited from the customer's account and credited to the merchant.


Before You Begin

Ensure you have:


Step 1: Request a Pre-Authorization

To initiate a pre-authorization, you'll need to send a POST request to the Create Payin endpoint and set the x-capture header to true.

Key Request Parameters

The request requires several key objects:

ParameterDescriptionRequired
beneficiaryRecipient details including bank information
senderSender information for compliance
merchantMerchant/business details
paymentMethodPayment method configuration
amountTransaction amount
currencyTransaction currency code
countryTarget country code

Example Request

Below is an example using curl:

curl --request POST \
  --url https://api.stage.localpayment.com/api/payin/ \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <your_access_token>' \
  --header 'Content-Type: application/json' \
  --header 'x-capture: true' \
  --data '{
    "paymentMethod": {
        "type": "CreditCard",
        "code": "1000",
        "flow": "DIRECT"
    },
    "externalId": "40bac59a-0381-4cc0-a6a5-33418d84c2e4",
    "country": "ARG",
    "currency": "ARS",
    "amount": 1000,
    "accountNumber": "{{accountNumber}}",
    "conceptCode": "0001",
    "merchant": {
        "type": "COMPANY",
        "name": "Company",
        "document": {
            "type": "CUIT",
            "id": "3000091105"
        },
        "email": "[email protected]",
        "phone": {
            "countryCode": "54",
            "areaCode": "351",
            "number": "1234567"
        }
    },
    "payer": {
        "type": "INDIVIDUAL",
        "name": "John",
        "lastname": "Doe",
        "document": {
            "type": "DNI",
            "id": "37993123"
        },
        "email": "[email protected]",
        "phone": {
            "countryCode": "1",
            "areaCode": "11",
            "number": "98189123"
        },
        "bank": {
            "name": "BANCO BBVA ARGENTINA S.A.",
            "code": "017",
            "account": {
                "type": "S",
                "number": "19101196551119123456789"
            }
        }
    },
    "commercialData": {
        "items": [
            {
                "id": "12345",
                "quantity": "1",
                "description": "Test product",
                "title": "Test",
                "unitPrice": "1000"
            }
        ]
    },
    "card": {
        "number": "4000000000000002",
        "cvv": "123",
        "expirationMonth": "12",
        "expirationYear": "2029"
    }
}'

See all available parameters in the request.


Step 2: Handle the Response

Successful Response

A successful response includes detailed transaction information and tracking identifiers

{
  "transactionType": "PayIn",
  "externalId": "40bac59a-0381-4cc0-a6a5-33418d84c2e4",
  "internalId": "22b29c98-92af-44bd-a164-1863ae2f1bb3",
  "paymentMethod": {
    "type": "CreditCard",
    "code": "1000",
    "flow": "DIRECT"
  },
  "country": "ARG",
  "currency": "ARS",
  "amount": 1000,
  "accountNumber": "{{accountNumber}}",
  "confirmed": {
    "currency": "ARS",
    "amount": 1000,
    "fxQuote": 1,
    "exchangeRateToken": null
  },
  "payment": {
    "installment": null,
    "currency": "ARS",
    "fxQuote": 1,
    "financingFee": 0,
    "amount": 1000
  },
  "localTaxes": [],
  "withHoldings": [],
  "fees": {
    "description": "Fee",
    "currency": "ARS",
    "fxSource": 210.8,
    "fxQuote": 1,
    "amount": 13.02,
    "account": "{{accountNumber}}"
  },
  "status": {
    "code": "102",
    "description": "AUTHORIZED",
    "detail": "The payin was authorized"
  },
  "ticket": null,
  "qr": null,
  "beneficiary": null,
  "merchant": {
    "type": "COMPANY",
    "name": "Company"
  },
  "payer": {
    "type": "INDIVIDUAL",
    "name": "John",
    "lastname": "Doe",
    "document": {
      "id": "37895247",
      "type": "DNI"
    },
    "email": "[email protected]",
    "phone": {
      "countryCode": "1",
      "areaCode": "11",
      "number": "98789632"
    },
    "address": null,
    "birthdate": null,
    "nationality": null
  },
  "intermediaries": [],
  "wireInstructions": null,
  "date": {
    "creationDate": "2024-05-19T19:02:44.018+00:00",
    "processedDate": "2024-05-19T19:02:44.799618",
    "expirationDate": "0001-01-01T00:00:00"
  },
  "card": {
    "bin": "402670",
    "brand": "VISA",
    "country": "RS",
    "name": "John Doe",
    "last4": "3263",
    "expirationYear": 2029,
    "expirationMonth": 9
  },
  "errors": []
}

Key Response Fields

FieldDescriptionUse Case
internalIdLocalpayment's unique transaction identifierTransaction tracking and support
externalIdYour reference numberInternal reconciliation
status.codeCurrent transaction status codeStatus monitoring
date.creationDateWhen transaction was createdAudit trail
date.processedDateWhen transaction began processingProcessing time calculation

Error Response

When a request fails, you'll receive detailed error information:

{
  "externalId": "46014bdc-c3a7-1b15-8dcf-c7050c1c8199",
  "internalId": "caa4e9aa-f634-497c-ba75-7f88b005ca62",
  "status": {
    "code": "801",
    "description": "REJECTED",
    "detail": "Params error"
  },
  "errors": [
    {
      "code": "300",
      "detail": "Invalid param + [paymentMethod] + doesn´t exists for MEX"
    },
    {
      "code": "300",
      "detail": "Invalid param + [payer.bank.account.[number, type | alias]] + must not be null"
    },
    {
      "code": "300",
      "detail": "Invalid param + [payer.document.type] + is invalid for country MEX"
    },
    {
      "code": "300",
      "detail": "Invalid param + [payer.document] + is invalid for payer type"
    },
    {
      "code": "701",
      "detail": "IncorrectAccountNumber"
    }
  ]
}

Step 3: Capture the funds

After pre-authorizing a transaction, you must capture the funds to debit the customer's account. Ensure that the capture request is for the full amount of the pre-authorization. The pre-authorization hold on the funds will expire after 7 days. If you do not capture the funds within this period, they will be automatically released back to the customer's card.

To capture a pre-authorization, send a PATCH request to the Capture Authorized Payin endpoint.

Example Request

curl --location --request PATCH 'https://api.stage.localpayment.com/api/payin/capture/{externalId}' \
--header 'Authorization: Bearer <your_access_token>'

Successful Response

{
    "externalId": "40bac59a-0381-4cc0-a6a5-33418d84c2e4",
    "internalId": "40ae5d95-e859-4fc9-b37b-67442392b785",
    "status": {
        "code": "103",
        "description": "APPROVED",
        "detail": "The payin was confirmed but not credited yet"
    }
}

Release Unused Funds

In order to ensure a positive customer experience, it is recommended to release any pre-authorized funds that will not be used. By initiating a release through an API request, you can avoid having your customers wait the full 7 days for the automatic release.

To release unused funds, send a PATCH request to the Cancel Payin Authorization endpoint.

Example Request

curl --location --request PATCH 'https://api.stage.localpayment.com/api/payin/capture/{externalId}/status/' \
--header 'Authorization: Bearer <your_access_token>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "status": "CANCELLED"
}'

Successful Response

{
    "externalId": "40bac59a-0381-4cc0-a6a5-33418d84c2e4",
    "internalId": "39eb0371-3f21-488f-a779-913799e51406",
    "status": {
        "code": "905",
        "description": "CANCELLED",
        "detail": "The authorization was cancelled"
    }
}

Step 4: Track Transaction Status

After initiating a pre-authorized payment, monitor its progress through these methods:

Common Status Codes

The Localpayment API provides various status codes to indicate the progress and outcome of the payment in the response.

CodeStatusDescription
103APPROVEDThe payin was confirmed but not credited yet.
200CompletedThe payin was completed.
701RejectedInvalid bank account number.
📝

For complete status code reference, see the Transaction Status documentation.

Testing Your Integration

Test Scenarios

Verify your integration handles these scenarios:

  1. Successful Transaction: Standard payin flow
  2. Validation Errors: Invalid bank account, missing fields
  3. Processing Delays: Transactions that take time to process
  4. Failed Transactions: Insufficient funds, blocked beneficiaries
  5. Status Updates: Webhook handling and status polling

Next Steps

After a pre-authorization is processed, you may need to perform additional actions, such as: