互动
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
6.8 KiB

package pay_service
import (
"fmt"
"github.com/chanxuehong/wechat/mch/mmpaymkttransfers"
"github.com/chanxuehong/wechat/mch/mmpaymkttransfers/promotion"
"hudongzhuanjia/logger"
"hudongzhuanjia/models"
"hudongzhuanjia/utils"
"hudongzhuanjia/utils/define"
"strconv"
)
// 企业向微信用户个人付款(不支持沙箱环境)
type TransferResponse struct {
DeviceInfo string `xml:"device_info,omitempty" json:"device_info,omitempty"`
NonceStr string `xml:"nonce_str,omitempty" json:"nonce_str,omitempty"`
PartnerTradeNo string `xml:"partner_trade_no,omitempty" json:"partner_trade_no,omitempty"`
PaymentNo string `xml:"payment_no,omitempty" json:"payment_no,omitempty"`
PaymentTime string `xml:"payment_time,omitempty" json:"payment_time,omitempty"`
}
func Transfer(desc, openId, partnerTradeNo string, amount int) (*TransferResponse, error) {
client, err := Client()
if err != nil {
return nil, err
}
nonceStr := utils.RandomStr(32)
if partnerTradeNo == "" { // 需要提前存入
partnerTradeNo = utils.RandomStr(32)
}
// 初始化参数结构体
body := make(map[string]string)
body["nonce_str"] = nonceStr
body["partner_trade_no"] = partnerTradeNo
body["openid"] = openId
body["check_name"] = "NO_CHECK" // NO_CHECK:不校验真实姓名 , FORCE_CHECK:强校验真实姓名
body["amount"] = fmt.Sprintf("%d", amount) // 企业付款金额,单位为分
body["desc"] = desc // 企业付款备注,必填。注意:备注中的敏感词会被转成字符*
body["mchid"] = define.MchId
body["mch_appid"] = client.AppId()
m, err := promotion.Transfers(client, body)
// 记录错误信息
if err != nil {
transfer := new(models.UserTransfer)
transfer.UpdateErrMsg(partnerTradeNo, err.Error())
return nil, err
}
res := &TransferResponse{
DeviceInfo: m["device_info"],
NonceStr: m["nonce_str"],
PartnerTradeNo: m["partner_trade_no"],
PaymentNo: m["payment_no"],
PaymentTime: m["payment_time"],
}
// 获取某些信息
transfer := new(models.UserTransfer)
exist, err := transfer.GetByPartnerTradeNo(partnerTradeNo)
if err != nil {
return nil, err
}
transfer.Desc = desc
transfer.OpenId = openId
transfer.PartnerTradeNo = partnerTradeNo
transfer.PaymentAmount = amount
transfer.PaymentNo = res.PaymentNo
transfer.DeviceInfo = res.DeviceInfo
transfer.PaymentTime = res.PaymentTime
if !exist {
_, err = transfer.Add()
if err != nil {
return nil, err
}
} else {
_, err = transfer.UpdateByPartnerTradeNo(partnerTradeNo)
if err != nil {
return nil, err
}
}
return res, nil
}
type TransferInfoResponse struct {
ErrCode string `json:"err_code"`
Status string `json:"status"`
Reason string `json:"reason"`
Openid string `json:"openid"`
PaymentAmount int `json:"payment_amount"`
PaymentTime string `json:"payment_time"`
TransferTime string `json:"transfer_time"`
Desc string `json:"desc"`
}
func TransferInfo(partnerTradeNo string) (*TransferInfoResponse, error) {
client, err := Client()
if err != nil {
return nil, err
}
nonceStr := utils.RandomStr(32)
var body = make(map[string]string, 0)
body["nonce_str"] = nonceStr
body["partner_trade_no"] = partnerTradeNo
m, err := mmpaymkttransfers.GetTransferInfo(client, body)
if err != nil {
transfer := new(models.UserTransfer)
transfer.UpdateErrMsg(partnerTradeNo, err.Error())
return nil, err
}
amount, _ := strconv.Atoi(m["payment_amount"])
res := &TransferInfoResponse{
Status: m["status"],
Reason: m["reason"],
Openid: m["openid"],
PaymentAmount: amount,
PaymentTime: m["payment_time"],
TransferTime: m["transfer_time"],
Desc: m["desc"],
ErrCode: m["err_code"],
}
transfer := new(models.UserTransfer)
if res.Status == define.CODE_SUCCESS {
transfer.Status = 2
} else if res.Status == define.CODE_TRANSFER_PROCESSING {
transfer.Status = 1
} else if res.Status == define.CODE_FAIL {
transfer.Status = 3
}
transfer.Reason = res.Reason
transfer.TransferTime = res.TransferTime
_, err = transfer.UpdateByPartnerTradeNo(partnerTradeNo)
if err != nil {
return nil, err
}
return res, nil
}
type RedPackResult struct {
MchBillno string `xml:"mch_billno,omitempty" json:"mch_billno,omitempty"`
ReOpenid string `xml:"re_openid,omitempty" json:"re_openid,omitempty"`
TotalAmount int `xml:"total_amount,omitempty" json:"total_amount,omitempty"`
SendListid string `xml:"send_listid,omitempty" json:"send_listid,omitempty"`
}
// 发送红包
func SendRedPack(sendName, openId, wishing, actName, remark string, totalAmount, totalNum, scene int) (*RedPackResult, error) {
client, err := Client()
if err != nil {
logger.Error("client init error: %v", err)
return nil, err
}
mchBillNo := utils.RandomStr(28)
nonceStr := utils.RandomStr(32)
body := make(map[string]string, 0)
body["mch_id"] = client.MchId()
//body["sub_mch_id"] = client.SubMchId()
body["wxappid"] = client.AppId()
//body["msgappid"] = define.WxAppId
body["nonce_str"] = nonceStr
body["mch_billno"] = mchBillNo
body["send_name"] = sendName
body["re_openid"] = openId
body["total_amount"] = fmt.Sprintf("%d", totalAmount)
body["total_num"] = fmt.Sprintf("%d", totalNum)
body["wishing"] = wishing
body["client_ip"] = define.ClientIp
body["act_name"] = actName
body["remark"] = remark
body["scene_id"] = fmt.Sprintf("PRODUCT_%d", scene)
m, err := mmpaymkttransfers.SendRedPack(client, body)
if err != nil {
return nil, err
}
res := &RedPackResult{
MchBillno: m["mch_billno"],
ReOpenid: m["re_openid"],
TotalAmount: totalAmount,
SendListid: m["send_listid"],
}
return res, nil
}
type QueryRedPackResult struct {
CommonReturn
CommonResult
MchBillno string `xml:"mch_billno,omitempty" json:"mch_billno,omitempty"`
Mchid string `xml:"mchid,omitempty" json:"mchid,omitempty"`
DetailId string `xml:"detail_id,omitempty" json:"detail_id,omitempty"`
Status string `xml:"status,omitempty" json:"status,omitempty"`
SendType string `xml:"send_type,omitempty" json:"send_type,omitempty"`
HbType string `xml:"hb_type,omitempty" json:"hb_type,omitempty"`
TotalNum int `xml:"total_num,omitempty" json:"total_num,omitempty"`
TotalAmount int `xml:"total_amount,omitempty" json:"total_amount,omitempty"`
Reason string `xml:"reason,omitempty" json:"reason,omitempty"`
SendTime string `xml:"send_time,omitempty" json:"send_time,omitempty"`
RefundTime string `xml:"refund_time,omitempty" json:"refund_time,omitempty"`
RefundAmount int `xml:"refund_amount,omitempty" json:"refund_amount,omitempty"`
Wishing string `xml:"wishing,omitempty" json:"wishing,omitempty"`
Remark string `xml:"remark,omitempty" json:"remark,omitempty"`
ActName string `xml:"act_name,omitempty" json:"act_name,omitempty"`
}