I’m using Drupal’s Commerce Square Connect Module to process credit card payments on my website. When I customer attempts to submit a payment with some error, such as an invalid CVV code, the error is detected and the request is rejected. The problem is that when the error is corrected by the customer and the payment request is submitted a second time, the request is again rejected with this error:
{"errors": [{"code": "CARD_TOKEN_USED","detail": "Card nonce already used with a different idempotency key; please request new nonce.","category": "INVALID_REQUEST_ERROR"}]}
I submitted a bug report some time ago. There’s been no response from the project maintainers, so I’d like to suggest a patch for them to consider. Here’s the code:
$orders_api_request = $orders_api->createOrder($order_request);
if ($orders_api_request->isSuccess()) {
$order_response = $orders_api_request->getResult();
// Create payment request.
$payment_request = new CreatePaymentRequest(
$payment_method->getRemoteId(),
uniqid('', TRUE)
);
$payment_request->setAmountMoney($square_total_money);
$payment_request->setOrderId($order_response->getOrder()->getId());
$payment_request->setAutocomplete($capture);
$payment_request->setIdempotencyKey(uniqid('', TRUE));
$payment_request->setBuyerEmailAddress($payment->getOrder()->getEmail());
$payment_request->setBillingAddress($billing_address);
// Create payment.
$payment_api = $api_client->getPaymentsApi();
$payment_api_request = $payment_api->createPayment($payment_request);
if ($payment_api_request->isSuccess()) {
$payment_response = $payment_api_request->getResult();
$next_state = $capture ? 'completed' : 'authorization';
$payment->setState($next_state);
$payment->setRemoteId($payment_response->getPayment()->getId());
if (!$capture) {
$expires = $this->time->getRequestTime() + (3600 * 24 * 6) - 5;
$payment->setExpiresTime($expires);
}
$payment->save();
}
else {
throw ErrorHelper::convertException(
new ApiException(
$payment_api_request->getBody(),
$payment_api_request->getRequest(),
NULL
),
$payment,
);
}
Where in the code above is the correct place to request a new nonce, and what’s the correct API call to make?