Square API로 등록된 상품에 대한 결제 수행

Square API를 사용하여 자사 EC 사이트에 결제 기능을 구현했습니다.
Square API의 도입, 샘플의 구현에 대해서는 @goofmint 씨의 PHP로 Square E 상거래 결제 시도 를 참고로 했습니다.

샘플에서는 금액이 지정된 요청을 만들고 Transactions API Charge를 실행하여 결제를 수행했습니다.

\SquareConnect\Configuration::getDefaultConfiguration()->setAccessToken($access_token);
$transactions_api = new \SquareConnect\Api\TransactionsApi();

//リクエストを作成
$request_body = array (
  "card_nonce" => $nonce,
  "amount_money" => array (
    "amount" => 100,
    "currency" => "JPY"
  ),
  "idempotency_key" => uniqid()
);

try {
  //決済実行
  $result = $transactions_api->charge($location_id, $request_body);
} catch (\SquareConnect\ApiException $e) {
  echo "Caught exception!<br/>";
  $result = $e->getResponseBody();      
}


이번에, Square 대시보드로 미리 등록되어 있는 상품에 대해 결제를 실행함으로써
대시보드상에서 재고 관리나 상위 매출 상품의 체크 등을 할 수 있도록 합니다.

상품에 대한 결제를 실행하는 흐름



샘플에서 사용하는 Transactions API, Locations API 외에도,
Catalog API, Orders API를 사용하여 결제를 실행합니다.
  • Square 대시 보드에 제품 등록
  • Catalog API의 SearchCatalogObjectsRequest를 실행하여 제품 목록을 가져옵니다.
  • CreateOrderRequestLineItem 만들기
  • Order API createOrder 실행
  • Order Id를 사용하여 Transactions API의 Charge를 실행합니다.

    상품은 등록되어 있는 것을 전제로, 2로부터의 실장을 봐 갑니다.

    2. Catalog API로 상품 리스트 취득



    Catalog API의 객체를 만들고 SearchCatalogObjectRequest를 실행합니다.
    여기서 1점 빠지는 포인트가, 현시점에서 Catalog API는 sandbox 환경에서의 동작에 대응하고 있지 않습니다.
    그러므로 이 테스트를 할 때에는 각 환경 ID는 프로덕션의 것을 사용해 주세요.
    5의 Charge까지 실행하면 당연합니다만 카드에 대해 과금이 행해져 버리기 때문에,
    테스트 후 Square 대시보드에서 매출을 환불해 주십시오.
    
    $catalog_api = new SquareConnect\Api\CatalogApi();
    $body = new \SquareConnect\Model\SearchCatalogObjectsRequest();
    
    try {
        $result = $catalog_api->searchCatalogObjects($body);
        echo "<pre>";
        print_r($result);
        echo "</pre>";
    } catch (Exception $e) {
        echo 'Exception when calling CatalogApi->searchCatalogObjects: ', $e->getMessage(), PHP_EOL;
    }
    

    등록 상품 리스트(SearchCatalogObjectsResponse Object)를 취득할 수 있었습니다.
    ※ 하늘의 항목이 매우 많기 때문에 이번 중요하지 않은 부분에 대해서 일부 생략하고 있습니다
    SquareConnect\Model\SearchCatalogObjectsResponse Object
    (
        [errors:protected] => 
        [cursor:protected] => 
        [objects:protected] => Array
        (
            [0] => SquareConnect\Model\CatalogObject Object
            (
                 [type:protected] => ITEM
                 [id:protected] => IRNEEEFLOKSIWONIPCZNRUHF
                 [updated_at:protected] => 2019-01-23T01:56:57.294Z
                 [version:protected] => 1548208617294
                 [present_at_all_locations:protected] => 1
                 [item_data:protected] => SquareConnect\Model\CatalogItem Object
                 (
                     [name:protected] => 塩バターパン
                     [description:protected] => ほんのりバター香る人気No.1のパンです
                     ...(略)...
                     [tax_ids:protected] => Array
                     (
                         [0] => HFCCV3RNRA5V75JEMD4QTLDF
                     )
                     [modifier_list_info:protected] => 
                     [image_url:protected] => 
                     [variations:protected] => Array
                     (
                         [0] => SquareConnect\Model\CatalogObject Object
                         (
                             [type:protected] => ITEM_VARIATION
                             [id:protected] => QBORT2E36FKXPNLY42EMWPBA
                             [updated_at:protected] => 2019-01-23T01:56:57.294Z
                             [version:protected] => 1548208617294
                             [item_variation_data:protected]=>SquareConnect\Model\CatalogItemVariation Object
                             (
                                 [item_id:protected] => IRNEEEFLOKSIWONIPCZNRUHF
                                 [name:protected] => 販売価格
                                 [sku:protected] => 
                                 [upc:protected] => 
                                 [pricing_type:protected] => FIXED_PRICING
                                 [price_money:protected] => SquareConnect\Model\Money Object
                                 (
                                     [amount:protected] => 160
                                     [currency:protected] => JPY
                                 )
                              )
                          )
                      )
                 )
            )
        )
    )
    

    3. CreateOrderRequestLineItem 만들기



    Orders API에 요청할 제품(LineItem)을 만듭니다.
    2에서 얻은 SearchCatalogObjectsResponse Object의 variables에서 id를 추출하고,
    CreateOrderRequestLineItem에 id, 개수를 설정하고 array에 저장합니다.
    구입하는 상품이 복수 있는 경우는 여기에서 추가해 가게 됩니다.
    
    $item_id = $result['objects'][0]['item_data']['variations'][0][id];
    $item = new \SquareConnect\Model\CreateOrderRequestLineItem;
    $item->setCatalogObjectId($item_id);
    $item->setQuantity('1');
    
    $lineItems = array();   
    array_push($lineItems, $item);
    

    4. Order API createOrder 실행



    3에서 만든 LineItems와 uniqid()를 설정하여 CreateOrderRequest를 만들고,
    Orders API createOrder를 실행합니다.
    $orders_api = new SquareConnect\Api\OrdersApi();
    $request = new \SquareConnect\Model\CreateOrderRequest();
    $request->setIdempotencyKey(uniqid());
    $request->setLineItems($lineItems);
    
    try {
        $result = $orders_api->createOrder($location_id, $request);
    
    }catch (Exception $e) {
        echo '<pre>';
        echo 'Exception when calling OrdersApi->createOrder:', $e->getMessage(), PHP_EOL;
    }
    

    이제 상품을 지정한 주문이 작성되었습니다.
    CreateOrderResponse는 다음과 같습니다. (일부 생략)
    SquareConnect\Model\CreateOrderResponse Object
    (
        [order:protected] => SquareConnect\Model\Order Object
        (
            [id:protected] => WBOP7aUfNxFGuSZk8wsgmswFsVHZY
             [location_id:protected] => 325X8D9WZ2239
             [reference_id:protected] => 
             [line_items:protected] => Array
             (
                 [0] => SquareConnect\Model\OrderLineItem Object
                 (
                     [name:protected] => 塩バターパン
                     [quantity:protected] => 1
                     [note:protected] => 
                     [catalog_object_id:protected] => QBORT2E36FKXPNLY42EMWPBA
                     [variation_name:protected] => 販売価格
                    ・・・(略)・・・
                     [total_money:protected] => SquareConnect\Model\Money Object
                     (
                         [amount:protected] => 160
                         [currency:protected] => JPY
                     )
                )
          )
         [total_money:protected] => SquareConnect\Model\Money Object
         (
             [amount:protected] => 160
             [currency:protected] => JPY
         )
         ・・・(略)・・・
      )
        [errors:protected] => 
    )
    

    5. Order Id를 사용하여 Transactions API Charge 실행



    4의 응답에서 ChargeRequest로 지정하기 위해 Order Id와 total_money를 추출하고,
    ChargeRequest를 작성합니다. 샘플에서는 $request_body로 배열을 직접 만들었지만,
    이번에는 각각 값을 set하여 작성하고 있습니다.
    $order_id = $result['order']['id'];
    $amount_money = $result['order']['total_money']; 
    
    $chargeRequest = new \SquareConnect\Model\ChargeRequest();
    $chargeRequest->setIdempotencyKey(uniqid());
    $chargeRequest->setAmountMoney($amount_money);
    $chargeRequest->setCardNonce($nonce);
    $chargeRequest->setOrderId($order_id);
    
    try {
        $result = $transactions_api->charge($location_id, $chargeRequest);
    
    } catch (\SquareConnect\ApiException $e) {
        echo "Caught exception!<br/>";
        print_r("<strong>Response body:</strong><br/>");
        echo "<pre>"; var_dump($e->getResponseBody()); echo "</pre>";
        echo "<br/><strong>Response headers:</strong><br/>";
        echo "<pre>"; var_dump($e->getResponseHeaders()); echo "</pre>";
    }
    

    charge가 성공적으로 이루어지면 다음과 같은 응답이 반환됩니다.
    order_id로 올바르게 설정되었는지 확인할 수 있습니다.
    SquareConnect\Model\ChargeResponse Object
    (
        [errors:protected] => 
        [transaction:protected] => SquareConnect\Model\Transaction Object
            (
                [id:protected] => WBOP7aUfNxFGuSZk8wsgmswFsVHZY
                [location_id:protected] => 325X8D9WZ2239
                [created_at:protected] => 2019-01-23T04:27:33Z
                [tenders:protected] => Array
                    (
                        [0] => SquareConnect\Model\Tender Object
                            (
                                [id:protected] => BxL59X98I4YkuJaURkBR3vMF
                                [location_id:protected] => 325X8D9WZ2239
                                [transaction_id:protected] => WBOP7aUfNxFGuSZk8wsgmswFsVHZY
                                [created_at:protected] => 2019-01-23T04:27:31Z
                                [note:protected] => Online Transaction
                                [amount_money:protected] => SquareConnect\Model\Money Object
                                    (
                                        [amount:protected] => 160
                                        [currency:protected] => JPY
                                    )
                                [processing_fee_money:protected] => 
                                [customer_id:protected] => 
                                [type:protected] => CARD
                                [card_details:protected] => SquareConnect\Model\TenderCardDetails Object
                                    (
                                        [status:protected] => CAPTURED
                                        [card:protected] => SquareConnect\Model\Card Object
                                            (
                                                [id:protected] => 
                                                [card_brand:protected] => VISA
                                                [last_4:protected] => 2362
                                            )
                                        [entry_method:protected] => KEYED
                                    )
                                [cash_details:protected] => 
                            )
                    )
                [refunds:protected] => 
                [reference_id:protected] => 
                [product:protected] => EXTERNAL_API
                [client_id:protected] => 
                [shipping_address:protected] => 
                [order_id:protected] => WBOP7aUfNxFGuSZk8wsgmswFsVHZY
            )
    )
    

    Square 대시보드에서도 상품에 대한 매출이 반영되어 있는 것을 확인할 수 있었습니다.


    결론



    아직 일본어 문헌이 적고 Stack Overflow에서 검색하거나 참조를 번역하면서 읽고 진행하여 구현했습니다. 질문은 물론 실수 등 있으면 코멘트를 받을 수 있으면 다행입니다.
  • 좋은 웹페이지 즐겨찾기