iamport/rest-client

这是用于连接亚姆波特(iamport) REST API 的 PHP 客户端。

2.0.2 2022-05-13 10:59 UTC

This package is auto-updated.

Last update: 2024-09-23 13:10:03 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()方法,为了方便,只需传入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()

ResponseInterface响应类型不是实现了Promises/A+规范

基于Guzzle promises librarypromise对象也支持。

发生错误时返回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来使用。

例如,当服务器有多个时,将access token存储在公共存储库(如redis)中,而不是当前client服务器,此时可以直接创建client来使用。

有关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支付相关的
    • CancelReason - 在处理订单退款时使用的取消原因代码
    • OrderStatus - 商品订单状态
    • ClaimType - 与商品订单相关的索赔类型
    • ClaimCancel - 当索赔类型为取消时的状态
    • ClaimReturn - 当索赔类型为退货时的状态
    • ClaimExchange - 当索赔类型为换货时的状态
    • ClaimPurchaseDecisionHoldback - 当索赔类型为购买确认挂起时的状态
    • ClaimAdminCancel - 当索赔类型为直权取消时的状态
    • DeliveryMethod - 配送方式代码
    • DeliveryCompany - 当配送方式代码为快递、挂号、包裹时使用的快递公司代码
    • ReturnDeliveryMethod - 反馈请求时的反馈原因代码
    • ReturnReason - 反馈请求时的反馈配送方式代码
    • RejectHoldReason - 反馈挂起处理时的反馈挂起原因代码

修改器 & 访问器

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

修改器

通常也称为Setter,用于在Requset对象中设置值。

例如,在Payment::list()fromto值中,需要传递unix timestamp,但如果以下方式传递DateTime对象,则Payment Requset对象的Mutator会将该值转换为timestamp来传递。

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

如果您想自定义此类更改,则可以覆盖Requset对象的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条支付记录,但只有1条imp_uid支付记录查询失败,则会收到成功返回的2条支付记录而不是4xx、5xx等错误代码。

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"  
    }
  ]
}

特别是对于像Naver支付的商品发货处理等逻辑,商家需要对失败的条目进行重试等额外处理。

为了帮助简化此过程,当发生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

链接

变更日志

关于变更的详细信息,请参考 CHANGELOG

许可

MIT 许可证