hanirani_iamport / rest-client
这是一个用于连接亚美普(iamport) REST API的PHP客户端。
Requires
- php: >=7.1.8
- ext-json: *
- guzzlehttp/guzzle: ^7.0
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()
方法,为方便起见,仅传入请求对象即可提供一致的结果。
$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+ spec 的 promise
对象,而不是 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()
直接创建请求。
但是,需要直接实现 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。
例如,如果服务器有多个实例,可以在当前客户端服务器以外的公共存储(如 redis 等)中存储 access token,然后可以直接创建并使用该客户端。
有关 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 Pay 相关CancelReason
- 在处理商品订单退款时使用的取消原因代码OrderStatus
- 商品订单状态ClaimType
- 与商品订单相关的索赔类型ClaimCancel
- 当索赔类型为 取消 时的状态ClaimReturn
- 当索赔类型为 退货 时的状态ClaimExchange
- 当索赔类型为 换货 时的状态ClaimPurchaseDecisionHoldback
- 当索赔类型为 购买确认挂起 时的状态ClaimAdminCancel
- 当索赔类型为 直接取消 时的状态DeliveryMethod
- 配送方式代码DeliveryCompany
- 当配送方式代码为 快递、挂号、包裹 时使用的快递公司代码ReturnDeliveryMethod
- 在退货请求时使用的退货原因代码ReturnReason
- 在退货请求时使用的退货配送方式代码RejectHoldReason
- 在退货挂起处理时使用的退货挂起原因代码
修改器 & 访问器
当使用 Request
和 Response
对象时,通过 Accessor
、Mutator
方法来获取或设置值,而不是直接访问实例变量。其中,日期和配送方式代码、银行代码等需要转换的值将自动转换后获取或设置。
修改器
通常称为 Setter
,用于向 Request
对象中设置值。
例如,Payment::list()
的 from
、to
值应以 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
对象会像下面这样传递关于失败项的数据,您可以通过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
链接
变更日志
有关变更的详细信息,请参阅变更日志。