微信的app支付,为了实现ios跟安卓的同时使用,还有就是为了保证支付的安全性,所以把微信app支付中的统一下单跟签名都放在了服务器端,这里用的是yii2中的api接口处理的,在签名时也是遇到了一些问题,这里做一下总结:
微信app支付没有单独的包,微信的官方文档中也没有具体的服务器端的demo,所以第一次做还是很费劲的,所以就索性用微信公众号支付的包吧。
这是微信app在yii2中的目录截图:
跟微信公众号支付的包基本是一样的,只是在签名的时候,我做了一些改动:
控制器是这样的:
?php namespace api\modules\RestApi\modules\v1\controllers; use Yii; use api\modules\RestApi\controllers\CommonController; use common\lib\WxAppPay\WxPayApi; use common\models\Store; use common\models\AlipayRecord; use common\models\Order; use common\models\Paylog; use common\models\Cashrecord; use common\lib\WxAppPay\Extend\WxPay; use common\lib\WxAppPay\Extend\PayNotify; use common\lib\AliAppPay\lib\AlipayRsaNotify; use common\lib\AliAppPay\lib\AlipayRsaSubmit; class PaysController extends CommonController { public $modelClass = 'api\modules\RestApi\models\Order'; public function init() { parent::init(); $this->enableCsrfValidation = false; } public function actionView($id) //微信app的支付准备 { if (empty($id)) throw new \Exception('参数错误!'); $model = new $this->modelClass; $res = $model->isPayResult($id); //判断是否支付 $store = new Store(); $storeInfo = $store->getFrontOne(['id'=>$res['info']->storeid]); $WxPay = new WxPay(); try { //统一下单 $input = new \WxPayUnifiedOrder(); $input->SetBody("小程府-" . $storeInfo->name); //商品详情 $input->SetOut_trade_no($id); $input->SetTotal_fee($res['info']->yingshou * 100); //金额 $input->SetTime_start(date("YmdHis")); $input->SetTime_expire(date("YmdHis", time() + 600)); $input->SetGoods_tag("xcf");//商品标记 $input->SetNotify_url("http://api.xxx.cn/RestApi/v1/pays/notifywx/"); $input->SetTrade_type("APP"); $UnifiedOrderResult = WxPayApi::unifiedOrder($input); $apps = $WxPay->GetAppApiParameters($UnifiedOrderResult);//返回签名 return $this->ajaxReturn($apps); } catch (\Exception $e) { return $e->getMessage(); } } public function actionNotifywx(){ //微信app的回调 // $rsv_data = $GLOBALS ['HTTP_RAW_POST_DATA']; // $re = xmlarray($rsv_data);‘php://input', ‘r' // $rsv_data = file_get_contents('php://input'); $notify = new PayNotify(); $notify->Handle(false); }
这里用到的wxpay类也在common/lib/wxAppPay/Extend中,签名部分做了改动,代码如下:
public function GetAppApiParameters($UnifiedOrderResult) { if(!array_key_exists("appid", $UnifiedOrderResult)//公众账号id || !array_key_exists("prepay_id", $UnifiedOrderResult) || $UnifiedOrderResult['prepay_id'] == "") { throw new \WxPayException("参数错误"); } $jsapi = new \WxPayJsApiPay(); $jsapi->SetAppid($UnifiedOrderResult["appid"]);//重新设置公众号id $jsapi->SetPartnerid($UnifiedOrderResult["mch_id"]);//商户号id $jsapi->SetPrepayid($UnifiedOrderResult["prepay_id"]);//预支付id $jsapi->SetPackage("Sign=WXPay");//设置订单详情扩展字符串 $jsapi->SetNonceStr(WxPayApi::getNonceStr());//设置随机字符串 $timeStamp = time(); $jsapi->SetTimeStamp("$timeStamp");//设置支付时间戳 // $jsapi->SetSign($jsapi->MakeSign()); $parameters1 = $jsapi->GetValues();//获取设置的值 //签名要放到最后一步,把时间戳也要拿来签名 $jsapi->SetAppSign($parameters1); // $jsapi->setPackage_app("Sign=WXPay"); //将签名重新放到返回的值里返回 $parameters = $jsapi->GetValues();//获取设置的值 unset($parameters['package']); $parameters['package_app'] = "Sign=WXPay"; return $parameters; }
注意:上面的注释部分很重要,如果不按微信文档中的走,签名始终是失败的,那是相当痛苦的一件事
还有回调,跟微信公众号支付是一样的,这里我也把app支付的包提供出来:
百度云链接: http://pan.baidu.com/s/1eSkFlsQ 密码: ge2f 拿走不谢,如果遇到什么问题,可以qq联系!