微信的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联系!