> ## Documentation Index
> Fetch the complete documentation index at: https://primer.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Adjust authorization

export const ApiEndpoint = ({method, path}) => {
  const getMethodColor = method => {
    switch (method?.toUpperCase()) {
      case "GET":
        return "#0285c7";
      case "POST":
        return "#008d71";
      case "PUT":
        return "#16a34a";
      case "PATCH":
        return "#808080";
      case "DELETE":
        return "#dc2626";
      default:
        return "#6b7280";
    }
  };
  const getEndpointUrl = (method, path) => {
    const endpoints = {
      "POST /client-session": "/api-reference/v2.4/api-reference/client-session-api/create-a-client-session",
      "PATCH /client-session": "/api-reference/v2.4/api-reference/client-session-api/update-client-session",
      "POST /payments": "/api-reference/v2.4/api-reference/payments-api/create-a-payment",
      "POST /payments/<YOUR-PAYMENT-ID>/resume": "/api-reference/v2.4/api-reference/payments-api/resume-payment",
      "POST /payments/<YOUR-PAYMENT-ID>/adjust-authorization": "/api-reference/v2.4/api-reference/payments-api/adjust-authorized-amount",
      "POST /payments/<PAYMENT_ID>/cancel": "/api-reference/v2.4/api-reference/payments-api/cancel-payment",
      "POST /payments/<PAYMENT_ID>/refund": "/api-reference/v2.4/api-reference/payments-api/refund-payment",
      "GET /payments/<PAYMENT_ID>": "/api-reference/v2.4/api-reference/payments-api/get-a-payment",
      "GET /payment-instruments": "/api-reference/v2.4/api-reference/payment-methods-api/list-saved-payment-methods",
      "DELETE /payment-instruments/<PAYMENT_METHOD_TOKEN>": "/api-reference/v2.4/api-reference/payment-methods-api/delete-payment-method-payment-methods-token-delete"
    };
    const key = `${method?.toUpperCase()} ${path}`;
    return endpoints[key] || "#";
  };
  const getPrettyPath = (method, path) => {
    const pathMapping = {
      "POST /payments/<YOUR-PAYMENT-ID>/resume": "/payments/{paymentId}/resume",
      "POST /payments/<YOUR-PAYMENT-ID>/adjust-authorization": "/payments/{paymentId}/adjust-authorization",
      "POST /payments/<PAYMENT_ID>/cancel": "/payments/{paymentId}/cancel",
      "POST /payments/<PAYMENT_ID>/refund": "/payments/{paymentId}/refund",
      "GET /payments/<PAYMENT_ID>": "/payments/{paymentId}",
      "DELETE /payment-instruments/<PAYMENT_METHOD_TOKEN>": "/payment-instruments/{paymentMethodToken}"
    };
    const key = `${method?.toUpperCase()} ${path}`;
    return pathMapping[key] || path;
  };
  const methodColor = getMethodColor(method);
  const url = getEndpointUrl(method, path);
  const displayPath = getPrettyPath(method, path);
  return <div style={{
    display: "inline-flex",
    alignItems: "center",
    cursor: "pointer",
    margin: "2px 0",
    padding: "4px",
    paddingRight: "6px",
    background: "rgb(245, 245, 245)",
    borderRadius: "6px",
    whiteSpace: "nowrap",
    textDecoration: "none"
  }}>
      <a href={url} target="_blank" rel="noopener noreferrer" style={{
    textDecoration: "none",
    border: "none"
  }}>
        <span style={{
    display: "inline-block",
    whiteSpace: "nowrap",
    padding: "0 8px",
    fontSize: "13px",
    lineHeight: "23px",
    borderRadius: "6px",
    fontWeight: 400,
    backgroundColor: methodColor,
    color: "white",
    border: "none"
  }}>
          {method.toUpperCase()}
        </span>
        <code style={{
    padding: "0",
    marginLeft: "4px",
    fontFamily: "monospace",
    color: methodColor,
    border: "none",
    textDecorationColor: methodColor
  }}>
          {displayPath}
        </code>
      </a>
    </div>;
};

export const TxnTag = ({status}) => {
  const getStyles = status => {
    const baseStyle = {
      display: 'inline-block',
      padding: '4px 8px',
      borderRadius: '4px',
      fontSize: '13px',
      fontWeight: '400'
    };
    switch (status) {
      case "PENDING":
        return {
          ...baseStyle,
          backgroundColor: '#ececec',
          color: '#9f9f9f'
        };
      case "AUTHORIZED":
        return {
          ...baseStyle,
          backgroundColor: '#ecfdf5',
          color: '#047857'
        };
      case "SETTLED":
      case "PARTIALLY_SETTLED":
        return {
          ...baseStyle,
          backgroundColor: '#ecfdf5',
          color: '#047857'
        };
      case "DECLINED":
      case "FAILED":
        return {
          ...baseStyle,
          backgroundColor: '#fef2f2',
          color: '#dc2626'
        };
      case "CANCELLED":
        return {
          ...baseStyle,
          backgroundColor: '#fefce8',
          color: '#d78203'
        };
      case "SETTLING":
        return {
          ...baseStyle,
          backgroundColor: '#e0f2fe',
          color: '#0c4a6e'
        };
      default:
        return {
          ...baseStyle,
          backgroundColor: '#f3f4f6',
          color: '#374151'
        };
    }
  };
  return <span style={getStyles(status)}>{status}</span>;
};

<Note>
  This page is only relevant for card payments.
</Note>

## What is adjust authorization?

There are scenarios where the final amount of the payment is not known at payment creation (the initial authorization).

Adjust authorization, sometimes referred to as incremental authorization, is a mechanism that enables the authorized amount to be adjusted before finally capturing the payment. This gives merchants great flexibility to increase the amount authorized as conditions change or additional charges accrue.

This is the preferred implementation to:

* Capturing an amount greater than the authorized amount, which is more likely to be rejected by the card networks
* Canceling and reauthorizing for larger amount, which can incur additional processor fees and negatively affects the customer experience

<Note>
  The initial authorization is still necessary. As its name suggests, authorization adjustment aims to modify an authorization that happened previously for an estimated amount.
</Note>

Below are some use cases where authorization adjustment is applicable:

<Card title="Hospitality" icon="user-helmet-safety" horizontal>
  The final amount may change based on additional incurred costs after the initial payment.
</Card>

<Card title="Micromobility / Transport Renting" icon="chart-line" horizontal>
  The journey length is unknown at the beginning of the journey and so the amount to charge is also not known - it can
  only be estimated.
</Card>

<Card title="Food ordering/delivery" icon="burger" horizontal>
  An amount is usually authorized at the point of order creation but the final amount can vary up to when the delivery is complete, such as an additional tip or an updated order.
</Card>

## Availability

Adjust authorization is available for Visa, MasterCard, Amex, and Discover card networks, where these networks set specific rules around which businesses are able to adjust an authorization. Your eligibility is determined by your Merchant Category Code (MCC), where support is ultimately up to the issuer.

To access the feature, you will need to use a processor on Primer that supports this capability. Below are the processors currently supported on Primer for adjust authorization:

* Checkout.com
* Paygent

Primer is extending the usage across all our connected processors where it’s supported. If there is a processor you use that isn’t currently available, please reach out to your CSM.

<Note>
  Primer is the underlying payment infrastructure and you should still speak to your processor before implementing authorization adjustment to ensure it’s enabled for your account for each card network.
</Note>

## Get Started with adjust authorization

<Note>
  Only available on API >= v2.2
</Note>

You can implement adjust authorization in 3 steps:

1. Authorize the payment with an estimated amount
2. Adjust the estimated amount by calling <ApiEndpoint method="POST" path="/payments/<YOUR-PAYMENT-ID>/adjust-authorization" />
3. Capture the final amount

### Step 1: Create estimated authorization

First, you need to pass the flag `authorizationType` = `ESTIMATED` on either:

* <ApiEndpoint method="POST" path="/client-session" /> or <ApiEndpoint method="PATCH" path="/client-session" />
* <ApiEndpoint method="POST" path="/payments" /> if using the advanced manual SDK flow

`authorizationType` defaults to `FINAL` if not set to `ESTIMATED`. Authorization adjustments only work on estimated authorizations so without this step, any future attempts to adjust the authorization will not work.

#### POST or PATCH `/client-session`

```json JSON theme={"dark"}
// POST or PATCH /client-session
{
  "customerId": "customer-123",
  "amount": 2000,
  "currencyCode": "GBP",
  "orderId": "order-123",
	"paymentMethod": {
		"authorizationType": "ESTIMATED"
	}
}

// response - 200 OK
{
    "customerId": "customer-123",
    "orderId": "order-123",
    "amount": 2000,
    "currencyCode": "GBP",
    "paymentMethod": {
        "vaultOnSuccess": false,
        "authorizationType": "ESTIMATED"
    },
    "clientToken": "client-token-string",
    "clientTokenExpirationDate": "2023-11-15T10:30:36.020109"
}
```

As the `authorizationType` field is optional, it is only included in the response if it is passed on the request. So, by default, this field will not be included in the client session response unless you actively choose to pass it in the request.

#### POST /payments

```json JSON theme={"dark"}
// POST /payments
{
  "orderId": "order-123",
  "amount": 2000,
  "currencyCode": "GBP",
  "customerId": "customer-123",
  "paymentMethodToken": "payment-method-token",
  "paymentMethod": {
    "authorizationType": "ESTIMATED"
  }
}

// response - 200 OK
{
  "id": "kkdEwEEE",
  "date": "2023-03-21T15:36:16.367687",
  "status": "AUTHORIZED",
  "orderId": "order-123",
  "currencyCode": "GBP",
  "amount": 2000,
  "customerId": "customer-123",
  "paymentMethod": {
    "authorizationType": "ESTIMATED",
    "paymentMethodToken": "payment-method-token",
    ...
  },
  ...
}
```

`authorizationType` is always returned in the response to the `POST /payments` endpoint, even if it’s not included in the request - the default `FINAL` will be returned if it’s not set to `ESTIMATED` in the request.

Also, as is the case with all other fields, the `authorizationType` value provided in `POST /payments` takes priority over the client session value if you add the field to both requests.

### Step 2: Submit adjust authorization

When you want to adjust the authorization amount for a successful estimated authorization, send <ApiEndpoint method="POST" path="/payments/<YOUR-PAYMENT-ID>/adjust-authorization" /> and pass the `amount` field which should equal the new desired authorized amount:

```json JSON theme={"dark"}
// POST /payments/<payment_id>/adjust-authorization
{
	"amount": 5000
}

// response - 200 OK
{
  "id": "kkdEwEEE",
  "date": "2023-03-21T15:36:16.367687",
  "status": "AUTHORIZED",
  "orderId": "order-123",
  "currencyCode": "GBP",
  "amount": 5000,
  "customerId": "customer-123",
  "paymentMethod": {
    "authorizationType": "ESTIMATED",
    "paymentMethodToken": "payment-method-token",
    ...
  },
  ...
}
```

This API call is always synchronous and will not be successful if:

* `authorizationType` = `FINAL`
* `status` ≠ <TxnTag status="AUTHORIZED" />
* `paymentInstrumentType` ≠ `PAYMENT_CARD`
* the processor used on the initial estimated authorization does not support authorization adjustment.
* the amount is not correct (e.g. the processor only supports amount greater than the authorized amount)

<Note>
  See more about this endpoint in the [API reference](/api-reference/v2.4/api-reference/payments-api/adjust-authorized-amount), including examples of unsuccessful responses.
</Note>

You can submit multiple authorization adjustments but the rules around the number supported varies per processor and per network and this could result in failed adjust authorization requests. It’s recommended you confirm your expected use case with your processor.

### Step 3: Capture final amount

When you’re ready and the final amount has been authorized, simply capture the payment as usual and it will use the last authorized amount from the last successful authorization adjustment.

<Note>
  [See more here about how to capture a payment.](/manage-payments/capture-payment)
</Note>

## Additional information

* No webhook is sent for a successful adjust authorization as no payment status change has occurred. You can confirm the adjust authorization request is successful by the response to the API request as it is synchronous.

* The authorization adjustment event will appear in the payment timeline, including the request and response to the processor.

  <Frame caption="Adjust Authorization event in payment timeline">
    <img src="https://goat-assets.production.core.primer.io/marketing/payment-operations/external-docs/adjust-authorization/adjust-auth-timeline.png" />
  </Frame>

* Usually, an unsuccessful adjust authorization doesn’t impact the initial authorization but it’s advised you confirm this with your processor.
