iamport / rest-client
这是用于连接亚姆波特(iamport) REST API 的 PHP 客户端。
Requires
- php: >=7.1.8
- ext-json: *
- guzzlehttp/guzzle: ^6.3
Requires (Dev)
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 Endpoint
、Http verb
、request(form_data, query_string)
数据,
通过传入必需值来创建对象,则自动设置用于API通信的数据,
在IDE中使用时,可以获得 类型检查、值的存在性、自动完成 等支持。
提供的请求对象列表
个人认证API
托管API
- EscrowLogis
支付相关基本API
- 支付
- 取消支付
- 一次性订阅
- 再次订阅
- 订阅计划
- 取消订阅计划
- 订阅查询
支付预先信息注册&验证API
- PaymentPrepare
非认证支付账单管理API
- SubscribeCustomer
卡卡支付专用API
- Kakaopay
PAYCO 专用API
- Payco
naver支付专用API
-
NaverInquiry
-
NaverOrder
-
NaverPayment
-
NaverReturn
现金收据发放/管理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 library的promise
对象也支持。
发生错误时返回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()
直接创建请求。
但是,Exception
的catch
处理需要直接实现。
第三个参数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-Type
、Accept
、Authorization
等值,但如果想自定义或扩展,
可以直接创建guzzle client来使用。
例如,当服务器有多个时,将access token存储在公共存储库(如redis)中,而不是当前client服务器,此时可以直接创建client来使用。
有关handler
和middleware
的详细信息,请参阅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
- 反馈挂起处理时的反馈挂起原因代码
修改器 & 访问器
使用Requset
和Response
对象时,通过Accessor
、Mutator
方法获取或设置值,而不是直接访问实例变量。其中,日期、配送方式代码、银行代码等需要转换的值将自动转换并获取或设置。
修改器
通常也称为Setter
,用于在Requset
对象中设置值。
例如,在Payment::list()
的from
、to
值中,需要传递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
对象会像以下那样传递有关失败条目的数据,并可以通过Collection
的getFailed()
方法获取。
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
链接
变更日志
关于变更的详细信息,请参考 CHANGELOG。