Reputation: 21
I am trying to allow users to create monthly subscriptions via my website.
To achieve the above, I've followed Square's suggested flow:
1.5 Create a customer and obtain a customer_id. success!
Use source_id from step 1 to create a payment and obtain a payment_id. This was successfully.
Use payment_id returned from step 2 to save the card on file. This calls results in in an error:
This is the request sent in step 2:
public function createPayment($request) {
$response = Http::withHeaders(
[
'Authorization' => "Bearer " . $this->config['square']['access_token'],
'Content-Type' => 'application/json',
'Square-Version' => "2022-01-20",
]
)->post($this->config['square']['paymentsEndpoint'], [
"idempotency_key" => $request['source_id'],
"amount_money" => [
"amount" => $request['amount'],
"currency" => "USD",
],
"source_id" => $request['source_id'],
"autocomplete" => true,
"location_id" => $this->config['square']['locationId'],
"reference_id" => "creator-id-" . $request['id'],
]);
$created = json_decode($response);
if (isset($created->payment->id)) {
return $created->payment->id;
}
}
The above returns:
{#1522
+"payment": {#1485
+"id": "xmhTZnkyo9oZ9PH0eKdVfWwfvSJZY"
+"created_at": "2022-02-11T14:20:08.746Z"
+"updated_at": "2022-02-11T14:20:08.982Z"
+"amount_money": {#1513
+"amount": 100
+"currency": "USD"
}
+"status": "COMPLETED"
+"delay_duration": "PT168H"
+"source_type": "CARD"
+"card_details": {#1483
+"status": "CAPTURED"
+"card": {#1529
+"card_brand": "VISA"
+"last_4": "1111"
+"exp_month": 11
+"exp_year": 2023
+"fingerprint": "sq-1-up5lr5N9rhqnx9-2Ho9ZGmb-6_ldGkuEsjOhgzaJ5Xhuv7Qqv0wCBhms-hMLTh-y0Q"
+"card_type": "CREDIT"
+"prepaid_type": "NOT_PREPAID"
+"bin": "411111"
}
+"entry_method": "KEYED"
+"cvv_status": "CVV_ACCEPTED"
+"avs_status": "AVS_ACCEPTED"
+"statement_description": "SQ *DEFAULT TEST ACCOUNT"
+"card_payment_timeline": {#1528
+"authorized_at": "2022-02-11T14:20:08.856Z"
+"captured_at": "2022-02-11T14:20:08.982Z"
}
}
+"location_id": "LABQBPRYSFTE8"
+"order_id": "StJEDwNo1Q7eXeF0l8vD9Iaeac4F"
+"reference_id": "creator-id-1"
+"risk_evaluation": {#1527
+"created_at": "2022-02-11T14:20:08.856Z"
+"risk_level": "NORMAL"
}
+"total_money": {#1526
+"amount": 100
+"currency": "USD"
}
+"approved_money": {#1525
+"amount": 100
+"currency": "USD"
}
+"receipt_number": "xmhT"
+"receipt_url": "https://squareupsandbox.com/receipt/preview/xmhTZnkyo9oZ9PH0eKdVfWwfvSJZY"
+"delay_action": "CANCEL"
+"delayed_until": "2022-02-18T14:20:08.746Z"
+"application_details": {#1524
+"square_product": "ECOMMERCE_API"
+"application_id": "sandbox-sq0idb-FrLggaZMvpJBc2UDN3zKlg"
}
+"version_token": "mzLRfLZlX4n0M6DyXqkDeWqDx4nKy9zZM4Mz2UBlr9v6o"
}
}
Then this code calls the Cards endpoint to create a card:
public function createCard($request) {
$id = auth()->user()->id;
$user = User::find($id);
$subscription = Subscription::where('user_id', '=', $id)->get();
$response = Http::withHeaders(
[
'Authorization' => "Bearer " . $this->config['square']['access_token'],
'Content-Type' => 'application/json',
'Square-Version' => "2022-01-20",
]
)->post($this->config['square']['cardsEndpoint'], [
"idempotency_key" => $request['source_id'],
"source_id" => $request['source_id'],
"card" => [
"billing_address" => [
"address_line_1" => $subscription[0]['address_line_1'],
"address_line_2" => $subscription[0]['address_line_2'] ?? "",
"locality" => $subscription[0]['admin_area_2'],
"administrative_district_level_1" => $subscription[0]['admin_area_1'],
"postal_code" => $subscription[0]['postal_code'],
"country" => $subscription[0]['country_code'],
],
"cardholder_name" => $request['fullname'],
"customer_id" => $request['customer_id'],
"reference_id" => "creator-id-" . $request['id'],
],
]);
return json_decode($response);
}
This call returns:
{"errors":[{"category":"INVALID_REQUEST_ERROR","code":"INVALID_CARD_DATA","detail":"Invalid card data.","field":"source_id"}]}
I tried running this in both sandbox and production environment and receive the same results.
The card data used on the client side is as follows:
Alternatively, in regards to the card number, I have follow the following recommendation from the Subscription API and got the same result:
Call CreateCard to add a card on file using the payment token ("cnon:card-nonce-ok") that Square provides for Sandbox testing.
Can someone please help me figure this out?
Upvotes: 2
Views: 1469
Reputation: 47
I was facing the same issue and seem like the billing_address causing issue while binding with card. It work If I remove the billing_address and keep it simple :)
Square PHP SDK
$card = new \Square\Models\Card();
$card->setCustomerId($customer_id);
$body = new \Square\Models\CreateCardRequest(
uniqid(), // perfer version 5
$request->payment_token,
$card
);
return $this->client->getCardsApi()->createCard($body);
You can also try it via API.
Endpoint:https://connect.squareupsandbox.com/v2/cards
{
"idempotency_key": "62d683de53df21",
"source_id": "cnon:XYZ...", //one time payment use payment token
"card": {
"customer_id": "123213...",
}
Upvotes: 1