大体流程:
1.IOS端需要在iTunes Connect上面添加配置一些内购商品,并审核通过,每个内购商品有自己的唯一标识product_id。
2.PHP后端要有一套与之对应的内购商品、IOS应用唯一标识bundle_id和应用秘钥配置,以便用于验证。如下在tp5的config中做了配置:
//IOS内购配置 'applepay' =>[ 'bundle_id' => 'com.oyhdo.lws', //应用唯一标识 'products' => ['com.lws.good1','com.lws.good2','com.lws.good3'], //内购商品 'apple_secret' => '6666666' //应用密钥,在itunes中获取 ],
3.IOS端调起内购支付,支付成功后会返回票据receipt_data,IOS端需将此票据及其他参数提交给后端接口验证(建议加密)。
(后端接收到的receipt_data票据信息打印如下:)
array(3) { ["receipt"] => array(18) { ["receipt_type"] => string(17) "ProductionSandbox" ["adam_id"] => int(0) ["app_item_id"] => int(0) ["bundle_id"] => string(18) "com.oyhdo.lws" ["application_version"] => string(1) "1" ["download_id"] => int(0) ["version_external_identifier"] => int(0) ["receipt_creation_date"] => string(27) "2019-01-16 13:24:02 Etc/GMT" ["receipt_creation_date_ms"] => string(13) "1547645042000" ["receipt_creation_date_pst"] => string(39) "2019-01-16 05:24:02 America/Los_Angeles" ["request_date"] => string(27) "2019-01-16 13:26:00 Etc/GMT" ["request_date_ms"] => string(13) "1547645160103" ["request_date_pst"] => string(39) "2019-01-16 05:26:00 America/Los_Angeles" ["original_purchase_date"] => string(27) "2013-08-01 07:00:00 Etc/GMT" ["original_purchase_date_ms"] => string(13) "1375340400000" ["original_purchase_date_pst"] => string(39) "2013-08-01 00:00:00 America/Los_Angeles" ["original_application_version"] => string(3) "1.0" ["in_app"] => array(1) { [0] => array(11) { ["quantity"] => string(1) "1" ["product_id"] => string(15) "com.lws.good1" ["transaction_id"] => string(16) "1000000494954657" ["original_transaction_id"] => string(16) "1000000494954657" ["purchase_date"] => string(27) "2019-01-16 13:24:02 Etc/GMT" ["purchase_date_ms"] => string(13) "1547645042000" ["purchase_date_pst"] => string(39) "2019-01-16 05:24:02 America/Los_Angeles" ["original_purchase_date"] => string(27) "2019-01-16 13:24:02 Etc/GMT" ["original_purchase_date_ms"] => string(13) "1547645042000" ["original_purchase_date_pst"] => string(39) "2019-01-16 05:24:02 America/Los_Angeles" ["is_trial_period"] => string(5) "false" } } } ["status"] => int(0) ["environment"] => string(7) "Sandbox" }
4.PHP后端对票据进行验证,并执行一些业务逻辑。代码如下:
//IOS内购
public function applepay(){
$arr = ['code'=>0,'msg'=>'支付失败','data'=>[]];
$user_id = $_POST['user_id'];//用户id
$money = $_POST['money']; //支付金额
$receipt_data = $_POST['receipt_data'];//票据
if ($user_id && $money>0 && $receipt_data) {
//生成商家订单号
$order_no = 'IOS'.time().rand(10000,99999);
/**
添加订单记录
省略逻辑......
**/
if($order_log){
//验证收据
$res = $this->validate_applepay($receipt_data,false); //false沙盒 true正式
if(intval($res['status'])==0) { //验证成功
$bundleId = config('bundle_id');
$products = config('products');
$bundle_id = $res['receipt']['bundle_id'];
$product_id = $res['receipt']['in_app'][0]['product_id'];
if($bundle_id==$bundleId && in_array($product_id,$products)){
//更新订单记录
$data['trade_no'] = $res['receipt']['in_app'][0]['transaction_id'];//内购交易订单号
$data['total_fee'] = $money; //总金额
$data['pay_time'] = time(); //支付成功时间
$data['state'] = 1;//修改订单状态
$updatelog = PayModel::updateLog($order_no,$data);
if($updatelog){
$arr['code'] = 200;
$arr['msg'] = '支付成功';
}
}else{
$arr['msg'] = '配置错误';
}
}else{ //验证失败
$arr['code'] = $res['status'];
}
}
}else{
$arr['msg'] = '参数错误';
}
echo json_encode($arr);
}
/**
* IOS内购验证票据
* @param string $receipt_data 付款后凭证
* @return array 验证是否成功
*/
private function validate_applepay($receipt_data,$sandbox=false){
$apple_secret = config('applepay.apple_secret');
$jsonData = array('receipt-data'=>$receipt_data,'password'=>$apple_secret);
$post_json = json_encode($jsonData);
if($sandbox){
$url="https://buy.itunes.apple.com/verifyReceipt";//正式环境
}else{
$url="https://sandbox.itunes.apple.com/verifyReceipt";//沙盒环境
}
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_json);
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result,true);
//返回status示例:
// * 0 验证成功
// * 21000 App Store不能读取你提供的JSON对象
// * 21002 receipt-data域的数据有问题
// * 21003 receipt无法通过验证
// * 21004 提供的shared secret不匹配你账号中的shared secret
// * 21005 receipt服务器当前不可用
// * 21006 receipt合法,但是订阅已过期。服务器接收到这个状态码时,receipt数据仍然会解码并一起发送
// * 21007 receipt是Sandbox receipt,但却发送至生产系统的验证服务
// * 21008 receipt是生产receipt,但却发送至Sandbox环境的验证服务
}
https://blog.csdn.net/msllws/article/details/86515824
8288分类目录声明:本站部分文章来源于网络,版权属于原作者所有。如有转载或引用文章/图片涉及版权问题,请联系我们处理.我们将在第一时间删除!
联系邮箱:tsk@qq.com