On this page
No Headings
Last updated: June 4, 2026
Extend the validity of an existing authorization when fulfillment takes longer than the initial authorization period. In the United States, authorizations are valid for 3 days, and up to 29 days in other regions. Reauthorization allows the merchant to keep funds available without requiring the buyer to re-approve payment.
Common scenarios include:
This integration uses the Payments API v2 to reauthorize an existing authorization and generate a new authorization with a refreshed expiration date.
Add the following endpoint to your existing server file from the quick start integration.
# Reauthorize for the same amount
curl -X POST https://api-m.sandbox.paypal.com/v2/payments/authorizations/AUTHORIZATION_ID/reauthorize \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-d '{}'
# Reauthorize for a higher amount (up to 115% of original)
curl -X POST https://api-m.sandbox.paypal.com/v2/payments/authorizations/AUTHORIZATION_ID/reauthorize \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-d '{
"amount": {
"currency_code": "USD",
"value": "115.00"
}
}'
# Get reauthorization status
curl -X GET https://api-m.sandbox.paypal.com/v2/payments/authorizations/NEW_AUTHORIZATION_ID \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ACCESS_TOKEN"// Add endpoint for reauthorization
app.post('/api/paypal/reauthorize-payment', async (req, res) => {
const { authorizationID, amount } = req.body;
if (!authorizationID) {
return res.status(400).json({ error: 'Missing authorizationID' });
}
const accessToken = await getPayPalAccessToken();
const apiBase = process.env.PAYPAL_API_BASE || 'https://api-m.sandbox.paypal.com';
const reauthorizeRequest = {
amount: amount || undefined // Optional: up to 115% of original amount
};
try {
const response = await fetch(
`${apiBase}/v2/payments/authorizations/${authorizationID}/reauthorize`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`,
},
body: JSON.stringify(reauthorizeRequest),
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Reauthorization failed');
}
const reauthorization = await response.json();
res.json({
status: 'REAUTHORIZED',
newAuthorizationId: reauthorization.id,
amount: reauthorization.amount,
expirationTime: reauthorization.expiration_time
});
} catch (err) {
if (err.message.includes('AUTHORIZATION_ALREADY_COMPLETED')) {
res.status(400).json({ error: 'Authorization already captured or voided' });
} else if (err.message.includes('REAUTHORIZE_NOT_ALLOWED')) {
res.status(400).json({ error: 'Reauthorization not allowed (too soon or expired)' });
} else {
res.status(500).json({ error: err.message });
}
}
});from paypalrestsdk import Api, Authorization
import os
# Configure PayPal SDK
api = Api({
'mode': 'sandbox',
'client_id': os.environ['PAYPAL_CLIENT_ID'],
'client_secret': os.environ['PAYPAL_CLIENT_SECRET']
})
# Process reauthorization
@app.route('/api/paypal/reauthorize-payment', methods=['POST'])
def reauthorize_payment():
try:
authorization_id = request.json.get('authorizationID')
amount = request.json.get('amount')
if not authorization_id:
return jsonify({'error': 'Missing authorizationID'}), 400
# Get authorization
authorization = Authorization.find(authorization_id)
# Reauthorize with optional amount
reauthorize_data = {}
if amount:
reauthorize_data['amount'] = {
'value': amount['value'],
'currency_code': amount.get('currency_code', 'USD')
}
# Execute reauthorization
reauthorization = authorization.reauthorize(reauthorize_data)
if reauthorization.success():
return jsonify({
'status': 'REAUTHORIZED',
'newAuthorizationId': reauthorization.id,
'amount': reauthorization.amount,
'expirationTime': reauthorization.expiration_time
})
else:
error = reauthorization.error
if error.get('name') == 'AUTHORIZATION_ALREADY_COMPLETED':
return jsonify({
'error': 'Authorization already captured or voided'
}), 400
elif error.get('name') == 'REAUTHORIZE_NOT_ALLOWED':
return jsonify({
'error': 'Reauthorization not allowed (too soon or expired)'
}), 400
else:
return jsonify({'error': error.get('message')}), 500
except Exception as e:
return jsonify({'error': str(e)}), 500import com.paypal.core.PayPalEnvironment;
import com.paypal.core.PayPalHttpClient;
import com.paypal.payments.AuthorizationsReauthorizeRequest;
import com.paypal.payments.Authorization;
import com.paypal.payments.Money;
HttpClient httpClient = new PayPalHttpClient(
new SandboxEnvironment(
System.getenv("PAYPAL_CLIENT_ID"),
System.getenv("PAYPAL_CLIENT_SECRET")
)
);
// Process reauthorization
@PostMapping("/api/paypal/reauthorize-payment")
public ResponseEntity<?> reauthorizePayment(
@RequestBody ReauthorizeRequest reauthorizeRequest
) {
try {
String authorizationId = reauthorizeRequest.getAuthorizationID();
if (authorizationId == null || authorizationId.isEmpty()) {
return ResponseEntity.badRequest().body(
Map.of("error", "Missing authorizationID")
);
}
AuthorizationsReauthorizeRequest request =
new AuthorizationsReauthorizeRequest(authorizationId);
// Set reauthorization amount if provided (up to 115% of original)
if (reauthorizeRequest.getAmount() != null) {
ReauthorizeRequestBody body = new ReauthorizeRequestBody()
.amount(new Money()
.value(reauthorizeRequest.getAmount().getValue())
.currencyCode(reauthorizeRequest.getAmount()
.getCurrencyCode() != null ?
reauthorizeRequest.getAmount().getCurrencyCode() : "USD")
);
request.requestBody(body);
}
HttpResponse<Authorization> response = httpClient.execute(request);
Authorization reauthorization = response.result();
return ResponseEntity.ok(Map.of(
"status", "REAUTHORIZED",
"newAuthorizationId", reauthorization.id(),
"amount", reauthorization.amount(),
"expirationTime", reauthorization.expirationTime()
));
} catch (HttpClientException e) {
String issue = extractIssue(e);
if ("AUTHORIZATION_ALREADY_COMPLETED".equals(issue)) {
return ResponseEntity.badRequest().body(
Map.of("error", "Authorization already captured or voided")
);
} else if ("REAUTHORIZE_NOT_ALLOWED".equals(issue)) {
return ResponseEntity.badRequest().body(
Map.of("error", "Reauthorization not allowed (too soon or expired)")
);
}
return ResponseEntity.status(500).body(
Map.of("error", e.getMessage())
);
}
}<?php
use PayPalCheckoutSdk\Core\SandboxEnvironment;
use PayPalCheckoutSdk\Core\PayPalHttpClient;
use PayPalCheckoutSdk\Payments\AuthorizationsReauthorizeRequest;
$environment = new SandboxEnvironment(
getenv('PAYPAL_CLIENT_ID'),
getenv('PAYPAL_CLIENT_SECRET')
);
$client = new PayPalHttpClient($environment);
// Process reauthorization
$app->post('/api/paypal/reauthorize-payment', function ($request, $response) use ($client) {
$body = $request->getParsedBody();
$authorizationID = $body['authorizationID'] ?? null;
if (!$authorizationID) {
$response->getBody()->write(json_encode([
'error' => 'Missing authorizationID'
]));
return $response->withStatus(400)->withHeader('Content-Type', 'application/json');
}
$reauthorizeRequest = new AuthorizationsReauthorizeRequest($authorizationID);
// Set reauthorization amount if provided (up to 115% of original)
if (isset($body['amount'])) {
$reauthorizeRequest->body = [
'amount' => [
'value' => $body['amount']['value'],
'currency_code' => $body['amount']['currency_code'] ?? 'USD'
]
];
}
try {
$reauthorizeResponse = $client->execute($reauthorizeRequest);
$reauthorization = $reauthorizeResponse->result;
$response->getBody()->write(json_encode([
'status' => 'REAUTHORIZED',
'newAuthorizationId' => $reauthorization->id,
'amount' => $reauthorization->amount,
'expirationTime' => $reauthorization->expiration_time
]));
return $response->withHeader('Content-Type', 'application/json');
} catch (HttpException $e) {
$statusCode = $e->statusCode;
$errorData = json_decode($e->getMessage(), true);
$issue = $errorData['details'][0]['issue'] ?? '';
if ($issue === 'AUTHORIZATION_ALREADY_COMPLETED') {
$response->getBody()->write(json_encode([
'error' => 'Authorization already captured or voided'
]));
return $response->withStatus(400)->withHeader('Content-Type', 'application/json');
} else if ($issue === 'REAUTHORIZE_NOT_ALLOWED') {
$response->getBody()->write(json_encode([
'error' => 'Reauthorization not allowed (too soon or expired)'
]));
return $response->withStatus(400)->withHeader('Content-Type', 'application/json');
}
$response->getBody()->write(json_encode([
'error' => $e->getMessage()
]));
return $response->withStatus(500)->withHeader('Content-Type', 'application/json');
}
});require 'paypal-sdk'
# Configure PayPal SDK
PayPal::SDK.configure(
:mode => "sandbox",
:app_id => ENV['PAYPAL_APP_ID'],
:client_id => ENV['PAYPAL_CLIENT_ID'],
:client_secret => ENV['PAYPAL_CLIENT_SECRET']
)
# Process reauthorization
post '/api/paypal/reauthorize-payment' do
request_body = JSON.parse(request.body.read)
authorization_id = request_body['authorizationID']
if authorization_id.nil? || authorization_id.empty?
status 400
return { error: 'Missing authorizationID' }.to_json
end
begin
# Get authorization
authorization = PayPal::SDK::PaymentsApi::Authorization.find(authorization_id)
# Prepare reauthorization data
reauthorize_data = {}
if request_body['amount']
reauthorize_data[:amount] = {
value: request_body['amount']['value'],
currency_code: request_body['amount']['currency_code'] || 'USD'
}
end
# Execute reauthorization
reauthorization = authorization.reauthorize(reauthorize_data)
if reauthorization.success?
content_type :json
{
status: 'REAUTHORIZED',
newAuthorizationId: reauthorization.id,
amount: reauthorization.amount,
expirationTime: reauthorization.expiration_time
}.to_json
else
error = reauthorization.error
if error['name'] == 'AUTHORIZATION_ALREADY_COMPLETED'
status 400
{ error: 'Authorization already captured or voided' }.to_json
elsif error['name'] == 'REAUTHORIZE_NOT_ALLOWED'
status 400
{ error: 'Reauthorization not allowed (too soon or expired)' }.to_json
else
status 500
{ error: error['message'] }.to_json
end
end
rescue => e
status 500
{ error: e.message }.to_json
end
end# Reauthorize for the same amount
curl -X POST http://localhost:3000/api/paypal/reauthorize-payment \
-H "Content-Type: application/json" \
-d '{"authorizationID": "5AB67890CD123456E"}'
# Expected success response:
# {"status":"REAUTHORIZED","newAuthorizationId":"8CD12345EF678901A","amount":{"currency_code":"USD","value":"100.00"},"expirationTime":"2024-02-05T10:23:23Z"}
# Reauthorize for a higher amount (up to 115% of original)
curl -X POST http://localhost:3000/api/paypal/reauthorize-payment \
-H "Content-Type: application/json" \
-d '{
"authorizationID": "5AB67890CD123456E",
"amount": {
"currency_code": "USD",
"value": "115.00"
}
}'
# Expected success response:
# {"status":"REAUTHORIZED","newAuthorizationId":"8CD12345EF678901A","amount":{"currency_code":"USD","value":"115.00"},"expirationTime":"2024-02-05T10:23:23Z"}// Test reauthorize for the same amount
const sameAmountResponse = await fetch('http://localhost:3000/api/paypal/reauthorize-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
authorizationID: '5AB67890CD123456E'
})
});
const sameAmount = await sameAmountResponse.json();
console.log('Reauthorized:', sameAmount);
// Expected: {"status":"REAUTHORIZED","newAuthorizationId":"8CD12345EF678901A","amount":{"currency_code":"USD","value":"100.00"},"expirationTime":"2024-02-05T10:23:23Z"}
// Test reauthorize for a higher amount (up to 115% of original)
const higherAmountResponse = await fetch('http://localhost:3000/api/paypal/reauthorize-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
authorizationID: '5AB67890CD123456E',
amount: {
currency_code: 'USD',
value: '115.00'
}
})
});
const higherAmount = await higherAmountResponse.json();
console.log('Reauthorized with higher amount:', higherAmount);
// Expected: {"status":"REAUTHORIZED","newAuthorizationId":"8CD12345EF678901A","amount":{"currency_code":"USD","value":"115.00"},"expirationTime":"2024-02-05T10:23:23Z"}import requests
# Test reauthorize for the same amount
same_amount_response = requests.post(
'http://localhost:3000/api/paypal/reauthorize-payment',
headers={'Content-Type': 'application/json'},
json={'authorizationID': '5AB67890CD123456E'}
)
print('Reauthorized:', same_amount_response.json())
# Expected: {"status":"REAUTHORIZED","newAuthorizationId":"8CD12345EF678901A","amount":{"currency_code":"USD","value":"100.00"},"expirationTime":"2024-02-05T10:23:23Z"}
# Test reauthorize for a higher amount (up to 115% of original)
higher_amount_response = requests.post(
'http://localhost:3000/api/paypal/reauthorize-payment',
headers={'Content-Type': 'application/json'},
json={
'authorizationID': '5AB67890CD123456E',
'amount': {
'currency_code': 'USD',
'value': '115.00'
}
}
)
print('Reauthorized with higher amount:', higher_amount_response.json())
# Expected: {"status":"REAUTHORIZED","newAuthorizationId":"8CD12345EF678901A","amount":{"currency_code":"USD","value":"115.00"},"expirationTime":"2024-02-05T10:23:23Z"}import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
// Test reauthorize for the same amount
String sameAmountBody = "{\"authorizationID\":\"5AB67890CD123456E\"}";
HttpRequest sameAmountRequest = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:3000/api/paypal/reauthorize-payment"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(sameAmountBody))
.build();
HttpResponse<String> sameAmountResponse = client.send(
sameAmountRequest,
HttpResponse.BodyHandlers.ofString()
);
System.out.println("Reauthorized: " + sameAmountResponse.body());
// Expected: {"status":"REAUTHORIZED","newAuthorizationId":"8CD12345EF678901A","amount":{"currency_code":"USD","value":"100.00"},"expirationTime":"2024-02-05T10:23:23Z"}
// Test reauthorize for a higher amount (up to 115% of original)
String higherAmountBody = "{\"authorizationID\":\"5AB67890CD123456E\",\"amount\":{\"currency_code\":\"USD\",\"value\":\"115.00\"}}";
HttpRequest higherAmountRequest = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:3000/api/paypal/reauthorize-payment"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(higherAmountBody))
.build();
HttpResponse<String> higherAmountResponse = client.send(
higherAmountRequest,
HttpResponse.BodyHandlers.ofString()
);
System.out.println("Reauthorized with higher amount: " + higherAmountResponse.body());
// Expected: {"status":"REAUTHORIZED","newAuthorizationId":"8CD12345EF678901A","amount":{"currency_code":"USD","value":"115.00"},"expirationTime":"2024-02-05T10:23:23Z"}<?php
// Test reauthorize for the same amount
$sameAmountData = json_encode([
'authorizationID' => '5AB67890CD123456E'
]);
$sameAmountResponse = file_get_contents(
'http://localhost:3000/api/paypal/reauthorize-payment',
false,
stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => $sameAmountData
]
])
);
echo "Reauthorized: " . $sameAmountResponse . "\n";
// Expected: {"status":"REAUTHORIZED","newAuthorizationId":"8CD12345EF678901A","amount":{"currency_code":"USD","value":"100.00"},"expirationTime":"2024-02-05T10:23:23Z"}
// Test reauthorize for a higher amount (up to 115% of original)
$higherAmountData = json_encode([
'authorizationID' => '5AB67890CD123456E',
'amount' => [
'currency_code' => 'USD',
'value' => '115.00'
]
]);
$higherAmountResponse = file_get_contents(
'http://localhost:3000/api/paypal/reauthorize-payment',
false,
stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => $higherAmountData
]
])
);
echo "Reauthorized with higher amount: " . $higherAmountResponse . "\n";
// Expected: {"status":"REAUTHORIZED","newAuthorizationId":"8CD12345EF678901A","amount":{"currency_code":"USD","value":"115.00"},"expirationTime":"2024-02-05T10:23:23Z"}require 'net/http'
require 'json'
# Test reauthorize for the same amount
uri = URI('http://localhost:3000/api/paypal/reauthorize-payment')
same_amount_request = Net::HTTP::Post.new(uri)
same_amount_request['Content-Type'] = 'application/json'
same_amount_request.body = {
authorizationID: '5AB67890CD123456E'
}.to_json
same_amount_response = Net::HTTP.start(uri.hostname, uri.port) do |http|
http.request(same_amount_request)
end
puts "Reauthorized: #{same_amount_response.body}"
# Expected: {"status":"REAUTHORIZED","newAuthorizationId":"8CD12345EF678901A","amount":{"currency_code":"USD","value":"100.00"},"expirationTime":"2024-02-05T10:23:23Z"}
# Test reauthorize for a higher amount (up to 115% of original)
higher_amount_request = Net::HTTP::Post.new(uri)
higher_amount_request['Content-Type'] = 'application/json'
higher_amount_request.body = {
authorizationID: '5AB67890CD123456E',
amount: {
currency_code: 'USD',
value: '115.00'
}
}.to_json
higher_amount_response = Net::HTTP.start(uri.hostname, uri.port) do |http|
http.request(higher_amount_request)
end
puts "Reauthorized with higher amount: #{higher_amount_response.body}"
# Expected: {"status":"REAUTHORIZED","newAuthorizationId":"8CD12345EF678901A","amount":{"currency_code":"USD","value":"115.00"},"expirationTime":"2024-02-05T10:23:23Z"}Run the following standard tests on your integration.
| Test scenario | Setup | Expected result |
|---|---|---|
| Successful reauthorization | Create authorization, wait 4+ days, reauthorize for same amount | New authorization created with a fresh expiration date. |
| Reauthorize for higher amount | Reauthorize for 110% of original amount | New authorization created for increased amount. |
| Reauthorize too soon | Attempt within 3 days of original authorization | Error: reauthorization not available yet. |
| Reauthorize expired authorization | Attempt after 30+ days | Error: authorization expired and cannot be reauthorized. |
| Reauthorize more than once | Reauthorize successfully, then attempt again | Error: cannot reauthorize more than once. |