setValidate(Validator::verify_serialnum($pay_sn)); $validate->setValidate(Validator::verify_number($pay_sn)); $error = $validate->validate(); if ($error != '') { return self::outerr(errcode::ErrParamter, $error); } $logic_payment = Logic('payment'); $member_info = array('member_id' => $_SESSION['member_id'], 'member_name' => $_SESSION['member_name']); $canuse_pred = $logic_payment->calcPredeposit($pay_sn,$member_info,$avail_pred,$used_pred); if($used_pred === false) { return self::outerr(errcode::ErrOrder,"取不到订单信息."); } else { return self::outsuccess(array("available_predeposit" => $avail_pred,"canuse_predeposit" => $canuse_pred,'used_predposit' => $used_pred)); } } /* * 微信获取支付数据 */ public function uniorderOp() { $pay_sn = $_GET['paysn']; $payment = $_GET['payment']; $vcode = $_GET['vcode']; if(empty($vcode)) { return self::outerr(errcode::ErrPayment, "抱歉,请升级到最新版本."); } if (in_array($payment, self::$pay_types) == false) { return self::outerr(errcode::ErrPayment, "err paytype {$payment}: only for wxpay,alipay"); } $logic_payment = Logic('payment'); // 尝试使用红包 $usebonus = intval($_GET['usebonus']); $member_info = array('member_id' => $_SESSION['member_id'], 'member_name' => $_SESSION['member_name']); if (intval($usebonus) === 1) { $logic_payment->payPredepositEx($pay_sn,$member_info); } //重新计算所需支付金额 $result = $logic_payment->getRealOrderInfo($pay_sn, $_SESSION['member_id']); if (intval($result['data']['api_pay_state']) != 0) { return self::outerr(errcode::ErrPayment, $result['msg']); } // 判断是否需要支付 $output = array(); $pay_money = intval(doubleval($result['data']['api_pay_amount']) * 100 + 0.5); if ($pay_money >= 1) { $output['need_pay'] = 1; $ret = $this->api_pay($result['data'], $payment); if ($ret != false) { $output['pay_info'] = $ret; } else { return self::outerr(errcode::ErrPayment, '支付失败.'); } } else { $output['need_pay'] = 0; $result = self::update_order($pay_sn, $pay_sn, 'bonus'); // 更新订单 // 推送到oms if (isset($result) && $result['state']) { if(is_pushoms()) { $logic_delivery = Logic('delivery'); $ret = $logic_delivery->putOrder($pay_sn, $pay_sn); if(empty($ret)) { //todo must add to 定时任务 Log::record("Put order to oms error: pay_sn={$pay_sn},bonus pay.",Log::ERR); } } } } self::outsuccess($output); } /** * 支付订单查询 * * 输入参数: * key: token * paysn: 支付sn * payment: 支付类型 * transaction_id: */ public function orderqueryOp() { $pay_sn = $_GET['paysn']; $payment = $_GET['payment']; $tractid = $_GET['transaction_id']; if ($payment == 'wxpay') { $input = new OpenWxPayOrderQuery(); $input->SetOut_trade_no($pay_sn); $input->SetTransaction_id($tractid); $result = OpenWxPayApi::orderQuery($input); if (array_key_exists("return_code", $result) && array_key_exists("result_code", $result) && $result["return_code"] == "SUCCESS" && $result["result_code"] == "SUCCESS" ) { return self::outsuccess($result); } return self::outerr(errcode::ErrPayment, '支付失败.'); } else { return self::outerr(errcode::ErrPayment, "错误的参数:payment = {$payment}"); } } /** * 支付返回 * * @param $pay_info * @param $payment * @return array */ private function api_pay($pay_info, $payment) { $subject = $pay_info['subject']; $pay_sn = $pay_info['pay_sn']; $fee = intval(doubleval($pay_info['api_pay_amount']) * 100 + 0.5); $order_sn = $pay_info['order_list'][0]['order_sn']; if ($payment == 'wxpay') { return $this->uniorder($subject, $pay_sn, $fee,$order_sn); } else if ($payment === 'alipay') { $ret = array(); $ret['rsa_private'] = self::alipay_rsa_private; // 私钥 $ret['partner'] = '2088121219613123'; // 合作者身份ID $ret['seller_id'] = 'napheir.ao@lrlz.com'; // 签约卖家支付宝账号 $ret['out_trade_no'] = $pay_sn; // 商户网站唯一订单号 $ret['subject'] = $subject; // 商品名称 $ret['body'] = "order_sn={$order_sn}"; // 商品详情 $total_fee = intval(doubleval($pay_info['api_pay_amount']) * 100 + 0.5) / 100; $ret['total_fee'] = $total_fee;// 商品金额 $ret['notify_url'] = self::ali_notifyurl; // 服务器异步通知页面路径 $ret['service'] = 'mobile.securitypay.pay'; // 服务器接口名称,固定值 $ret['payment_type'] = '1'; // 支付类型,固定值 $ret['_input_charset'] = 'utf-8'; // 参数编码,固定值 $ret['it_b_pay'] = '30m'; // 设置未付款交易的超时时间 30min $ret['return_url'] = 'http://'; // 支付宝完成请求后,当前页面跳转到商户指定页面的路径,可空 return array('payment' => $payment, 'content' => $ret); } } /** * 格式化参数格式化成url参数 */ private function to_url_params($values) { $buff = ""; foreach ($values as $k => $v) { if ($k != "sign" && $v != "" && !is_array($v)) { $buff .= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); return $buff; } private function make_sign($values) { //签名步骤一:按字典序排序参数 ksort($values); $string = $this->to_url_params($values); //签名步骤二:在string后加入KEY $string = $string . "&key=" . OpenWxPayConfig::KEY; //签名步骤三:MD5加密 $string = md5($string); //签名步骤四:所有字符转为大写 $result = strtoupper($string); return $result; } /** * 更新订单状态 * * @param $out_trade_no * @param $trade_no * @param $payment * @param $transaction_id * @return array */ public static function update_order($out_trade_no, $trade_no, $payment) { $logic_payment = Logic('payment'); $tmp = explode('|', $out_trade_no); $out_trade_no = $tmp[0]; if (!empty($tmp[1])) { $order_type = $tmp[1]; } else { $order_pay_info = Model('order')->getOrderPayInfo(array('pay_sn' => $out_trade_no)); if (empty($order_pay_info)) { $order_type = 'v'; } else { $order_type = 'r'; } } if ($order_type == 'r') { $result = $logic_payment->getRealOrderInfo($out_trade_no); if (intval($result['data']['api_pay_state'])) { return array('state' => true); } $order_list = $result['data']['order_list']; $result = $logic_payment->updateRealOrder($out_trade_no, $payment, $order_list, $trade_no); } elseif ($order_type == 'v') { $result = $logic_payment->getVrOrderInfo($out_trade_no, null, true); if ($result['data']['order_state'] != ORDER_STATE_NEW) { return array('state' => true); } $result = $logic_payment->updateVrOrder($out_trade_no, $payment, $result['data'], $trade_no); } return $result; } private function toString($order) { $ret = ''; foreach ($order as $key => $val) { $ret .= $key . "=" . $val; $ret .= '&'; } return $ret; } public static function check_fee($pay_sn,$total_fee,&$need_pay) { $logic_payment = Logic('payment'); $result = $logic_payment->getRealOrderInfo($pay_sn); if (intval($result['data']['api_pay_state']) != 0) { return false; } $need_pay = intval($result['data']['api_pay_amount'] * 100 + 0.5); $total_fee = intval($total_fee * 100 + 0.5); return ($need_pay === $total_fee); } /** * @return array * @throws OpenWxPayException */ private function uniorder($body, $pay_sn, $fee,$order_sn) { Log::record("body={$body},paysn={$pay_sn},fee={$fee}", Log::DEBUG); $input = new OpenWxPayUnifiedOrder(); $input->SetBody($body); //商品或支付单简要描述 $input->SetAttach($pay_sn); //附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 $out_trade_no = $pay_sn . sprintf("%03d",mt_rand(0,999)); //给微信用的每次重新生成的商户订单SN, 避免二次支付, 数额修改导致支付失败 $input->SetOut_trade_no($out_trade_no);//商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号 $input->SetTotal_fee("{$fee}");//订单总金额,单位为分,详见支付金额 $input->SetTime_start(date("YmdHis")); //订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则 $input->SetTime_expire(date("YmdHis", time() + 600));//订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则 $input->SetNotify_url(self::wx_notifyurl); $input->SetTrade_type("APP");//JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里,MICROPAY--刷卡支付,刷卡支付有单独的支付接口,不调用统一下单接口 $order = OpenWxPayApi::unifiedOrder($input); $sorder = $this->toString($order); Log::record($sorder, Log::DEBUG); if (array_key_exists('err_code', $order)) { return false; } $ret = array(); { $ret['appid'] = $order["appid"]; $ret['noncestr'] = OpenWxPayApi::getNonceStr(); $ret['package'] = 'Sign=WXPay'; $ret['partnerid'] = OpenWxPayConfig::MCHID; $ret['prepayid'] = $order['prepay_id']; $timeStamp = time(); $ret['timestamp'] = "{$timeStamp}"; $ret['sign'] = $this->make_sign($ret); } return $ret; } }