hanirani_iamport/rest-client

这是一个用于连接亚美普(iamport) REST API的PHP客户端。

2.0.2 2024-04-21 15:35 UTC

This package is auto-updated.

Last update: 2024-09-21 16:29:28 UTC


README

这是一个为PHP用户提供的亚美普REST API连接模块。

  • 基于 guzzle 构建的版本
  • 以composer包的形式提供

有关旧版PHP 5.X版本的连接模块,请参阅 1.0分支

要求

  • 需要PHP 7.1或更高版本。

快速入门

Iamport

  • callApi(Request) - 提供成功/失败的统一结果。
  • callApiPromise(Request) - 成功时返回promise对象。
  • request(method, uri, attributes, $client) - 返回API调用响应。
  • requestPromise(method, uri, attributes, $client) - 通过异步调用返回promise对象。
  • requestAccessToken() - 发放访问令牌。
  • getCustomHttpClient(HandlerStack) - 如果想直接创建guzzle客户端的handler,请调用此函数。

请求

请求对象已经预先定义了API EndpointHttp verbrequest(form_data, query_string)数据,

通过传递必需的参数来创建对象,则会自动设置用于API通信的数据,

在IDE中使用时,可以获得类型检查值的可用性自动完成等支持。

提供的请求对象列表

本人认证API

托管API

支付相关基本API

支付预先信息注册和验证API

非认证支付账单管理API

卡卡支付专用API

PAYCO专用API

naver支付专用API

现金收据发行/管理API

虚拟账户管理API

卡公司/银行信息API

结果

使用callApi()时,无论通信成功或失败,都会返回如下结构的统一Result对象。

Result {
    data : 응답 데이터 (Requset 객체)
    error : 에러정보
}

isSuccess() 方法可用于判断 API 调用是否成功,通过 getData()getError() 方法可以分别访问各自的值。data 中包含 Response 对象,而 error 返回 Rest API 服务器提供的错误信息和用于追踪的原始 Exception 对象。

// 성공 예시
Result {
  data : Payment {
    imp_uid: "imp_1234567"
    merchant_uid : "merchant_1234"
    // .. 생략
  }
  error : null
}

// 에러 예시
Result {
  data : null
  error : {
    "code": -1
    "message": "존재하지 않는 결제정보입니다."
    "previous": IamportException {
      request : Request {}
      response: Response {}
      handlerContext: {}
      message: "존재하지 않는 결제 정보입니다."
      code: 404,
      // .. 생략         
    }
  } 
}

使用方法

callApi()

内部通过直接调用 request() 方法,为方便起见,仅传入请求对象即可提供一致的结果。

$iamport = new Iamport('YOUR_IMP_REST_API_KEY', 'YOUR_IMP_REST_API_SECRET');

$payment = Payment::getImpUid('imps_410064014595');

$result = $iamport->callApi($payment);

if ($result->isSuccess()) {

    // 조회한 결제 정보
    $payment_data = $result->getData();

    // __get을 통해 API의 Response Model의 값들을 모두 property처럼 접근할 수 있습니다.
    // https://api.iamport.kr/#!/payments/getPaymentByImpUid 의 Response Model.
    $imp_uid = $payment_data->imp_uid;
    
    // Response 객체에서 편의를 위해 자체적으로 변환해주는 값들의 경우 ( ex: Unix timestamp -> Y-m-d H:is )
    // 변환값이 아닌 원본 property 접근은 getAttributes()를 사용합니다.
    $paid_at = $payment_data->paid_at;
    $original_paid_at = $payment->getAttributes('paid_at');

    if ( 결제검증 로직 ) {
        // 결제 성공 처리
    } else {
        // 결제 실패 처리
    }
} else {
    error_log($result->getError());
}

callApiPromise()

支持基于实现 Promises/A+ specpromise 对象,而不是 ResponseInterface 响应类型。

基于 Guzzle promises library 的实现。

当发生错误时返回 Result 结构体,成功时返回 promise 对象。

$iamport = new Iamport('YOUR_IMP_REST_API_KEY', 'YOUR_IMP_REST_API_SECRET');

try {

    $payment = Payment::getImpUid('imps_410064014595');
    
    $promise = $iamport->callApiPromise($payment);

    $promise->then(
        function (ResponseInterface $res) {
            // 성공시 로직
        },
        function (RequestException $e) {
            // 실패 로직
        }
    );

    // 강제완료
    $response = $promise->wait();

    // response Parsing
    $parsedResponse = json_decode($response->getBody());

    // 조회한 결제 정보
    $result = $parsedResponse->response

} catch (Exception $e) {
    // 예외처리
}

request()

如果不使用 callApi(),可以通过 request() 直接创建请求。

但是,需要直接实现 Exceptioncatch 处理。

第三个参数 request 的选项需要根据 Guzzle 文档 规范发送,

响应类型是 Psr\Http\Message\ResponseInterface

$iamport = new Iamport('YOUR_IMP_REST_API_KEY', 'YOUR_IMP_REST_API_SECRET');

try {

    // 조회한 결제 정보
    $result = $iamport->request('GET', 'http://api.iamport.kr/API_URI', [
        'body' => [
            // form data
        ],
        'query' => [
            // Query String
        ]
    ]);

} catch (Exception $e) {
    // 예외처리
}

getCustomHttpClient()

使用 callApi()callApiPromise()request()requestPromise() 时,会通过 middleware 自动设置如 Content-TypeAcceptAuthorization 等值,但如果想要自定义或扩展这些值,
可以直接创建并使用 guzzle client。

例如,如果服务器有多个实例,可以在当前客户端服务器以外的公共存储(如 redis 等)中存储 access token,然后可以直接创建并使用该客户端。

有关 handlermiddleware 的详细信息,请参考 guzzle 官方文档

$stack = HandlerStack::create();

// client stack에 추가할 기능들 구현
$stack->push(new CustomMiddleware());
$stack->push(new CustomTokenMiddleware());

$client = $iamport->getCustomHttpClient($stack);

// Request에 client 설정
$payment = Payment::getImpUid(imp_uid);
$payment->setClient($client);
$result = $iamport->callApi($payment);

// 직접호출시 client 설정
$result = $iamport->request(
    'GET',
    'https://https://api.iamport.kr/{API_URI}',
    [
        'body' => [
            // form data
        ],
        'query' => [
            // Query String
        ]
    ],
    true,
    $client
);

详细信息

枚举

提供用于存储如配送方式代码、快递公司代码、银行代码等值的 Enum 类。

Enum 类提供的功能

提供的 Enum 类列表

  • BankCode - 在虚拟账户查询时使用的银行代码(金融结算标准代码3位)
  • VbankCode - 在虚拟账户发行时允许使用的银行代码(金融结算标准代码3位)
  • PaycoStatus - 在更改 Payco 订单商品的状时使用的状态
  • PaymentSort - 在查询支付记录时进行排序
  • Naver - 与 Naver Pay 相关
    • CancelReason - 在处理商品订单退款时使用的取消原因代码
    • OrderStatus - 商品订单状态
    • ClaimType - 与商品订单相关的索赔类型
    • ClaimCancel - 当索赔类型为 取消 时的状态
    • ClaimReturn - 当索赔类型为 退货 时的状态
    • ClaimExchange - 当索赔类型为 换货 时的状态
    • ClaimPurchaseDecisionHoldback - 当索赔类型为 购买确认挂起 时的状态
    • ClaimAdminCancel - 当索赔类型为 直接取消 时的状态
    • DeliveryMethod - 配送方式代码
    • DeliveryCompany - 当配送方式代码为 快递、挂号、包裹 时使用的快递公司代码
    • ReturnDeliveryMethod - 在退货请求时使用的退货原因代码
    • ReturnReason - 在退货请求时使用的退货配送方式代码
    • RejectHoldReason - 在退货挂起处理时使用的退货挂起原因代码

修改器 & 访问器

当使用 RequestResponse 对象时,通过 AccessorMutator 方法来获取或设置值,而不是直接访问实例变量。其中,日期和配送方式代码、银行代码等需要转换的值将自动转换后获取或设置。

修改器

通常称为 Setter,用于向 Request 对象中设置值。

例如,Payment::list()fromto 值应以 unix timestamp 形式传递,但如果以 DateTime 对象的形式传递,则 Payment Request 对象的 Mutator 将该值转换为 timestamp 并传递值。

$requset = Payment::list('paid');
$request->to = new DateTime('2019-12-01 09:25:00');

如果想要自定义此更改过程,可以通过覆盖 Request 对象的 Mutator 方法来使用。

访问器

通常称为 Getter,用于获取 Response 对象的值。以 $response->{变量名} 这样的方式访问值时,将输出转换后的值;如果需要原始值,则可以使用 $response->getAttributes({变量名}) 方法来访问未转换的值。

$request = NaverInquiry::single('201901');
$response = $iamport->callApi($request);
$data = $response->getData();

# 변환된 값 출력
echo $data->product_order_status;   // 취소 완료
echo $data->shipping_due;           // 2018-08-23 23:59:59

# 원본 값 출력   
echo $data->getAttributes('product_order_status');  // CANCELED_BY_NOPAYMENT
echo $data->getAttributes('shipping_due');          // 1535036399

207 响应

一些 API 在多个响应结果中只有部分失败时,会产生 207 响应而不是错误。

例如,在请求了 3 条支付记录的情况下,如果只有一条 imp_uid 支付记录查询失败,则不会返回 4xx、5xx 等错误代码,而是只返回成功查询的 2 条支付记录,因此在后续处理过程中可能会错过失败记录并导致错误。

Payment:listImpUid([
    'imp_uid1',     
    'imp_uid2', 
    'wrong_imp_uid', // 잘못된 imp_uid
]);

// API 호출 과정 생략..

// 응답결과
Collection {
  items: array:2 [
    0 => Payment {
      imp_uid: "imp_uid1"
      .. 생략
    }
    1 => Payment {
      imp_uid: "imp_uid2"  
    }
  ]
}

尤其是不仅仅是简单查询,而是执行类似于NaverPay的商品发货处理等逻辑时,加盟店需要对失败的项进行重试等额外处理。

为了方便这个过程,当发生207响应时,Collection对象会像下面这样传递关于失败项的数据,您可以通过CollectiongetFailed()方法获取这些数据。

Collection {
  items: array:2 [
    0 => Payment {
      imp_uid: "imp_uid1"
      .. 생략
    }
    1 => Payment {
      imp_uid: "imp_uid2"
      .. 생략
    }
  ],
  failed: array:1 [
    0 => "wrong_imp_uid"
  ]
}

$data = $response->getData();

// 성공한 응답데이터 출력
echo $data->getItems());

// 실패한 건의 고유 ID 목록
echo $data->getFailed());

支持207响应的Response列表以及失败时返回的唯一值如下。

  • Payment : imp_uid
  • SubscribeCustomer : customer_uid
  • NaverProductOrder : product_order_id

next() & previous()

当以分页形式提供的Collection时,存在limit值,因此要查询其他页面,则需要重新分配page变量并再次进行API通信。

为了解决这种麻烦,提供了可以轻松获取前后数据的next()previous()方法。如果不存在前后数据,则返回null

$iamport = new Iamport($impKey, $impSecret);

$request = Payment::listMerchantUid('merchant_uid');
$response = $iamport->callApi($request);
$data = $response->getData();

// 다른 page 데이터 조회
$request->page = 2
$response = $iamport->callApi($request);
$nextData = $response->getData();

// next(), previous()를 이용한 조회
$previousData = $data->previous($iamport);
$nextData = $data->next($iamport);

示例

更详细的示例,请参考测试代码 - tests示例代码

测试

composer test

composer test

链接

变更日志

有关变更的详细信息,请参阅变更日志

许可证

MIT许可证