123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- <?php
- /**
- * Payments.php UTF-8
- *
- *
- * @date : 2017/5/2 14:50
- *
- * @license 这不是一个自由软件,未经授权不许任何使用和传播。
- * @author : wuyonghong <wyh@huosdk.com>
- * @version : HUOSDK 7.0
- */
- namespace huoMpay;
- use huo\controller\common\Base;
- use huo\controller\common\HuoSession;
- use huo\controller\pay\Notify;
- use huo\controller\pay\Sdk;
- use huo\controller\pay\SdkOrderCache;
- use huolib\constant\OrderConst;
- use huolib\constant\PaywayConst;
- use huolib\status\OrderStatus;
- use huolib\tool\StrUtils;
- use huomp\controller\game\GameMini;
- use huomp\model\wallet\MgmLogModel;
- use huomp\model\wallet\MidasGmMemModel;
- use think\Log;
- class Payments extends Base {
- const MGM_QUERY = 1; /* 1 查询 */
- const MGM_PAY = 2; /* 2 扣费 */
- const MGM_PRESENT = 3; /* 3 赠送 */
- const MGM_CANCEL = 4; /* 4 取消支付 */
- /**
- * 获取余额并且支付
- *
- * @param int $mem_id 玩家ID
- * @param string $order_id 订单ID
- *
- * @return array
- */
- public function getBalanceAndPay($mem_id, $order_id) {
- if (empty($order_id)) {
- $_code = OrderStatus::ORDER_ID_EMPTY;
- return $this->huoError($_code, OrderStatus::getMsg($_code));
- }
- $_soc_class = SdkOrderCache::ins();
- $_order_data = $_soc_class->getInfoByOrderId($order_id);
- if (empty($_order_data)) {
- $_code = OrderStatus::ORDER_ID_ERROR;
- return $this->huoError($_code, OrderStatus::getMsg($_code));
- }
- if ($mem_id != $_order_data['mem_id']) {
- $_code = OrderStatus::ORDER_NOT_EXISTS;
- return $this->huoError($_code, OrderStatus::getMsg($_code));
- }
- $mem_id = $_order_data['mem_id'];
- $_rdata['status'] = $_order_data['status'];
- $_rdata['cp_status'] = $_order_data['cp_status'];
- if (OrderConst::CP_STATUS_SUC != $_order_data['cp_status']
- && OrderConst::PAY_STATUS_SUC == $_order_data['status']) {
- $_rs = (new Notify())->notify($order_id);
- if (OrderStatus::NO_ERROR == $_rs['code']) {
- $_rdata['status'] = OrderConst::PAY_STATUS_SUC;
- $_rdata['cp_status'] = OrderConst::CP_STATUS_SUC;
- }
- $_code = OrderStatus::NO_ERROR;
- return $this->huoSuccess($_code, OrderStatus::getMsg($_code), $_rdata);
- }
- /* 获取余额 */
- $_rs = $this->midasGetBalance($mem_id, $order_id);
- if (OrderStatus::NO_ERROR != $_rs['code']) {
- return $this->huoError($_rs['code'], $_rs['msg']);
- }
- $_data = $_rs['data'];
- $_mgm_model = (new MidasGmMemModel());
- $_mgm_data = $_mgm_model->getDataOrInsert($mem_id, $_order_data['app_id']);
- $_diff_gm_cnt = StrUtils::formatNumber($_data['save_amt'] - $_mgm_data['m_save_amt']);
- /* 数量大于等于充值金额 */
- $_product_cnt = StrUtils::formatNumber($_order_data['product_cnt']);
- /* 变化的游戏币必须币充值的游戏币多 */
- if ($_diff_gm_cnt < $_product_cnt) {
- $_code = OrderStatus::NOTIFY_AMOUNT_ERROR;
- Log::write(
- "func=".__FUNCTION__."&class=".__CLASS__."&step1&code=".$_code.'&data.'
- .http_build_query($_data).'&order_data='.http_build_query($_order_data).'&mgm_data='.http_build_query(
- $_mgm_data
- ).'&diff_gm_cnt='.$_diff_gm_cnt.'&product_cnt='.$_product_cnt.'&rs='.json_encode($_rs),
- LOG::ERROR
- );
- return $this->huoError($_code, OrderStatus::getMsg($_code));
- }
- /* 扣除所有游戏币 */
- /* 获取余额 */
- $_rs = $this->midasPay($mem_id, $order_id);
- if (OrderStatus::NO_ERROR != $_rs['code'] && 90012 != $_rs['code']) {
- return $this->huoError($_rs['code'], $_rs['msg']);
- }
- $_rs = (new Notify())->payNotify(
- $_order_data['product_id'], $order_id, '', $_order_data['amount'], $_order_data['payway']
- );
- if (false == $_rs) {
- $_code = OrderStatus::INNER_ERROR;
- return $this->huoError($_code, OrderStatus::getMsg($_code));
- }
- /* 更新米大师游戏币 */
- $_mgm_data['m_balance'] = $_data['balance'] - $_product_cnt;
- $_mgm_data['m_gen_balance'] = $_data['gen_balance'];
- $_mgm_data['m_save_amt'] += $_product_cnt;
- $_mgm_data['m_save_sum'] = $_data['save_sum'];
- $_mgm_data['m_cost_sum'] = $_data['cost_sum'];
- $_mgm_data['m_present_sum'] = $_data['present_sum'];
- $_mgm_data['sum_money'] += $_order_data['amount'];
- $_mgm_data['total'] += $_product_cnt;
- $_mgm_data['remain'] += $_mgm_data['m_balance'];
- $_mgm_model->updateData($_mgm_data, $_mgm_data['id']);
- /* 插入每条记录 */
- // TODO: wuyonghong 2018/8/16 插入log记录
- /* 从订单中获取状态 */
- $_statues = (new Sdk())->getStatus($order_id);
- if (false == $_statues) {
- $_code = OrderStatus::ORDER_ID_ERROR;
- return $this->huoError($_code, OrderStatus::getMsg($_code), $_rdata);
- }
- $_code = OrderStatus::NO_ERROR;
- $_rdata = [
- 'order_id' => $order_id,
- 'status' => $_statues['status'],
- 'cp_status' => $_statues['cp_status']
- ];
- return $this->huoSuccess($_code, OrderStatus::getMsg($_code), $_rdata);
- }
- /**
- * @param string $app_id 应用ID
- * @param bool $is_sand 是否沙盒环境
- *
- * @return array
- */
- public function getBaseParam($app_id, $is_sand = false) {
- $_mpay_data = (new GameMini())->getMpayConf($app_id, $is_sand);
- $_rdata['appid'] = $_mpay_data['appid']; /* 小程序ID */
- $_rdata['offer_id'] = $_mpay_data['offer_id']; /* 米大师支付应用ID */
- $_rdata['ts'] = time();
- $_rdata['zone_id'] = '1';
- $_rdata['pf'] = 'android';
- $_rdata['app_secret'] = $_mpay_data['app_secret']; /* 小程序AppSecret */
- $_rdata['app_key'] = $_mpay_data['app_key']; /* 米大师AppKey */
- return $_rdata;
- }
- /**
- * @param int $mem_id
- * @param int $app_id
- *
- * @return string
- */
- public function getOpenId($mem_id, $app_id = 0) {
- $_open_id = (new HuoSession($mem_id, $app_id))->getOpenId();
- if (!empty($_open_id)) {
- return $_open_id;
- }
- return '';
- }
- /**
- * @param int $mem_id
- * @param int $app_id
- *
- * @return string
- */
- public function getSessionKey($mem_id, $app_id) {
- $_session_key = (new HuoSession($mem_id, $app_id))->getAccessToken();
- if (!empty($_session_key)) {
- return $_session_key;
- }
- return '';
- }
- /**
- * 开通了虚拟支付的小游戏,可以通过本接口查看某个用户的游戏币余额
- * https://developers.weixin.qq.com/minigame/dev/document/midas-payment/midasGetBalance.html
- *
- * @param int $mem_id 玩家ID
- * @param string $order_id 订单ID
- *
- * @return int|mixed
- */
- public function midasGetBalance($mem_id, $order_id = '') {
- $_order_data = SdkOrderCache::ins()->getInfoByOrderId($order_id);
- $_is_sand = true;
- if (PaywayConst::PAYWAY_MPAY == $_order_data['payway']) {
- $_is_sand = false;
- }
- $_app_id = $_order_data['app_id'];
- $_uri = '/cgi-bin/midas/getbalance';
- if ($_is_sand) {
- $_uri = '/cgi-bin/midas/sandbox/getbalance';
- }
- $_base_params = $this->getBaseParam($_app_id, $_is_sand);
- $_open_id = $this->getOpenId($mem_id, $_app_id);
- $_session_key = $this->getSessionKey($mem_id, $_app_id);
- $_params = [
- 'openid' => $_open_id,
- 'appid' => $_base_params['appid'],
- 'offer_id' => $_base_params['offer_id'],
- 'ts' => $_base_params['ts'],
- 'zone_id' => $_base_params['zone_id'],
- 'pf' => $_base_params['pf'],
- //'user_ip' => $_order_data['payext']['ip'],/* 用户外网 IP */
- ];
- $_mp_app_secret = $_base_params['app_secret']; /* 小程序AppSecret */
- $_midas_app_key = $_base_params['app_key']; /* 米大师密钥 */
- $_rs = MpaySign::apiPay($_uri, $_params, $_mp_app_secret, $_midas_app_key, $_session_key);
- if (OrderStatus::NO_ERROR == $_rs['code']) {
- $_mgm_log_data['mem_id'] = $mem_id;
- $_mgm_log_data['app_id'] = $_order_data['app_id'];
- $_mgm_log_data['order_id'] = $_order_data['order_id'];
- $_mgm_log_data['m_balance'] = $_rs['data']['balance'];
- $_mgm_log_data['m_gen_balance'] = $_rs['data']['gen_balance'];
- $_mgm_log_data['m_save_amt'] = $_rs['data']['save_amt'];
- $_mgm_log_data['m_save_sum'] = $_rs['data']['save_sum'];
- $_mgm_log_data['m_cost_sum'] = $_rs['data']['cost_sum'];
- $_mgm_log_data['m_present_sum'] = $_rs['data']['present_sum'];
- $_mgm_log_data['server_id'] = $_base_params['zone_id'];
- $_mgm_log_data['type'] = self::MGM_QUERY;
- (new MgmLogModel())->insertLog($_mgm_log_data);
- }
- return $_rs;
- }
- /**
- * 开通了虚拟支付的小游戏,若扣除游戏币的订单号在有效时间内,可以通过本接口取消该笔扣除游戏币的订单
- * https://developers.weixin.qq.com/minigame/dev/document/midas-payment/midasCancelPay.html
- *
- *
- * @param int $mem_id 玩家ID
- * @param string $order_id 订单ID
- *
- * @return array|mixed
- */
- function midasCancelPay($mem_id, $order_id) {
- $_order_data = SdkOrderCache::ins()->getInfoByOrderId($order_id);
- $_is_sand = true;
- if (PaywayConst::PAYWAY_MPAY == $_order_data['payway']) {
- $_is_sand = false;
- }
- $_app_id = $_order_data['app_id'];
- $_uri = '/cgi-bin/midas/cancelpay';
- if ($_is_sand) {
- $_uri = '/cgi-bin/midas/sandbox/cancelpay';
- }
- $_base_params = $this->getBaseParam($_app_id, $_is_sand);
- $_open_id = $this->getOpenId($mem_id);
- $_session_key = $this->getSessionKey($mem_id);
- $_params = [
- 'openid' => $_open_id,
- 'appid' => $_base_params['appid'],
- 'offer_id' => $_base_params['offer_id'],
- 'ts' => $_base_params['ts'],
- 'zone_id' => $_base_params['zone_id'],
- 'pf' => $_base_params['pf'],
- //'user_ip' => $_order_data['payext']['ip'],/* 用户外网 IP */
- 'bill_no' => $_order_data['order_id'],
- // 'pay_item' => $_order_data['payext']['product_name'], /* 道具名称 */
- ];
- $_mp_app_secret = $_base_params['app_secret']; /* 小程序AppSecret */
- $_midas_app_key = $_base_params['app_key']; /* 米大师密钥 */
- $_rs = MpaySign::apiPay($_uri, $_params, $_mp_app_secret, $_midas_app_key, $_session_key);
- if (OrderStatus::NO_ERROR == $_rs['code']) {
- $_mgm_log_data['mem_id'] = $mem_id;
- $_mgm_log_data['app_id'] = $_order_data['app_id'];
- $_mgm_log_data['order_id'] = $_order_data['order_id'];
- $_mgm_log_data['type'] = self::MGM_CANCEL;
- (new MgmLogModel())->insertLog($_mgm_log_data);
- }
- return $_rs;
- }
- /**
- * 米大师付款
- * 开通了虚拟支付的小游戏,可以通过本接口扣除某个用户的游戏币。
- * 由于可能存在接口调用超时或返回系统失败,但是游戏币实际已经扣除的情况,所以当该接口返回系统失败时,可以用相同的bill_no再次调用本接口,直到返回非系统失败为止,不会重复扣款,也可以调用取消支付接口取消本次扣款。
- * https://developers.weixin.qq.com/minigame/dev/document/midas-payment/midasPay.html
- *
- *
- * @param int $mem_id 玩家ID
- * @param string $order_id 订单ID
- *
- * @return array|mixed
- */
- function midasPay($mem_id, $order_id) {
- $_order_data = SdkOrderCache::ins()->getInfoByOrderId($order_id);
- $_is_sand = true;
- if (PaywayConst::PAYWAY_MPAY == $_order_data['payway']) {
- $_is_sand = false;
- }
- $_app_id = $_order_data['app_id'];
- $_uri = '/cgi-bin/midas/pay';
- if ($_is_sand) {
- $_uri = '/cgi-bin/midas/sandbox/pay';
- }
- $_base_params = $this->getBaseParam($_app_id, $_is_sand);
- $_open_id = $this->getOpenId($mem_id, $_app_id);
- $_session_key = $this->getSessionKey($mem_id, $_app_id);
- $_params = [
- 'openid' => $_open_id,
- 'appid' => $_base_params['appid'],
- 'offer_id' => $_base_params['offer_id'],
- 'ts' => $_base_params['ts'],
- 'zone_id' => $_base_params['zone_id'],
- 'pf' => $_base_params['pf'],
- // 'user_ip' => $_order_data['payext']['ip'],
- // 'pay_item' => $_order_data['payext']['product_name'],
- // 'app_remark' => $_order_data['payext']['remark'],
- 'amt' => $_order_data['product_cnt'], /* 扣除游戏币数量,不能为 0 */
- 'bill_no' => $_order_data['order_id'],
- ];
- $_mp_app_secret = $_base_params['app_secret']; /* 小程序AppSecret */
- $_midas_app_key = $_base_params['app_key']; /* 米大师密钥 */
- $_rs = MpaySign::apiPay($_uri, $_params, $_mp_app_secret, $_midas_app_key, $_session_key);
- if (OrderStatus::NO_ERROR == $_rs['code']) {
- $_mgm_log_data['mem_id'] = $mem_id;
- $_mgm_log_data['app_id'] = $_order_data['app_id'];
- $_mgm_log_data['order_id'] = $_rs['data']['bill_no'];
- $_mgm_log_data['m_balance'] = $_rs['data']['balance'];
- $_mgm_log_data['m_used_gen_balance'] = isset($_rs['data']['used_gen_amt'])
- ? $_rs['data']['used_gen_amt'] : 0;
- $_mgm_log_data['type'] = self::MGM_PAY;
- (new MgmLogModel())->insertLog($_mgm_log_data);
- }
- return $_rs;
- }
- /**
- * 米大师赠送
- * 开通了虚拟支付的小游戏,可以通过该接口赠送游戏币给某个用户。
- * https://developers.weixin.qq.com/minigame/dev/document/midas-payment/midasPresent.html
- *
- *
- * @param int $mem_id 玩家ID
- * @param string $order_id 订单ID
- * @param int $present_counts 赠送游戏币的个数,不能为0
- *
- *
- * 0 请求成功
- * -1 系统繁忙,此时请开发者稍候再试
- * 90009 mp_sig签名错误
- * 90010 用户未登录或登录态已过期
- * 90011 sig签名错误
- * 90012 订单已存在
- * 90017 没有调用接口的权限
- * 90018 参数错误
- *
- * @return array|mixed
- */
- function midasPresent($mem_id, $order_id, $present_counts) {
- $_order_data = SdkOrderCache::ins()->getInfoByOrderId($order_id);
- $_is_sand = true;
- if (PaywayConst::PAYWAY_MPAY == $_order_data['payway']) {
- $_is_sand = false;
- }
- $_app_id = $_order_data['app_id'];
- $_uri = '/cgi-bin/midas/present';
- if ($_is_sand) {
- $_uri = '/cgi-bin/midas/sandbox/present';
- }
- $_base_params = $this->getBaseParam($_app_id, $_is_sand);
- $_open_id = $this->getOpenId($mem_id);
- $_session_key = $this->getSessionKey($mem_id);
- $_params = [
- 'openid' => $_open_id,
- 'appid' => $_base_params['appid'],
- 'offer_id' => $_base_params['offer_id'],
- 'ts' => $_base_params['ts'],
- 'zone_id' => $_base_params['zone_id'],
- 'pf' => $_base_params['pf'],
- // 'user_ip' => $_order_data['payext']['ip'],
- 'bill_no' => $_order_data['order_id'],
- 'present_counts' => $present_counts, /* 赠送游戏币的个数,不能为0 */
- ];
- $_mp_app_secret = $_base_params['app_secret']; /* 小程序AppSecret */
- $_midas_app_key = $_base_params['app_key']; /* 米大师密钥 */
- $_rs = MpaySign::apiPay($_uri, $_params, $_mp_app_secret, $_midas_app_key, $_session_key);
- if (OrderStatus::NO_ERROR == $_rs['code']) {
- $_mgm_log_data['mem_id'] = $mem_id;
- $_mgm_log_data['app_id'] = $_order_data['app_id'];
- $_mgm_log_data['order_id'] = $_rs['data']['bill_no'];
- $_mgm_log_data['m_balance'] = $_rs['data']['balance'];
- $_mgm_log_data['type'] = self::MGM_PRESENT;
- (new MgmLogModel())->insertLog($_mgm_log_data);
- }
- return $_rs;
- }
- }
|