package paymob import ( "encoding/json" "fmt" "math" "net/http" "strconv" "strings" "bet24.com/log" "bet24.com/public" coreClient "bet24.com/servers/coreservice/client" "bet24.com/servers/payment/config" "bet24.com/servers/payment/db" "bet24.com/servers/payment/shop" "github.com/gin-gonic/gin" ) // 下单 func PayOrder(c *gin.Context) { obj := db.NewOrder(db.SP_paymob_ORDER) if err := c.ShouldBind(&obj.In); err != nil { log.Debug("%s query params err %v", "payMob.PayOrder", err) c.String(http.StatusOK, "") return } obj.In.IpAddress = strings.Split(c.Request.RemoteAddr, ":")[0] //// 币种为空,根据ip获取 //if obj.In.Currency == "" { // currency := shop.GetCurrencyRateByIp(obj.In.UserID, obj.In.IpAddress) // obj.In.Currency = currency //} // 获取产品信息 item := shop.GetProduct(obj.In.ProductID) if item == nil { log.Error("%s query GetProduct productId=%s currency=%s is nil", "paymob.PayOrder", obj.In.ProductID, obj.In.Currency) c.String(http.StatusOK, "") return } //// 获取当前汇率信息 //info := shop.GetExchangeRate(obj.In.Currency) //if info == nil { // log.Error("%s query GetExchangeRate obj.In.Currency=%s is nil", "paymob.PayOrder", obj.In.Currency) // c.String(http.StatusOK, "") // return //} // //// 计算价格 //calPrice := info.Rate * item.Price // //// 检查价格是否篡改 //if calPrice != obj.In.Price { // log.Error("%s obj.In.Price=%v info.Rate=%v calPrice=%v is invalid", "paymob.PayOrder", obj.In.Price, info.Rate, calPrice) // c.String(http.StatusOK, "") // return //} // 检查价格是否篡改 if item.Price != obj.In.Price { log.Error("%s obj.In.Price=%v calPrice=%v is invalid", "paymob.PayOrder", obj.In.Price, item.Price) c.String(http.StatusOK, "") return } obj.DoAction(nil) if obj.Out.OrderID == "" { log.Debug("%s GenOrder fail obj.In=%+v", "payMob.PayOrder", obj.In) c.String(http.StatusOK, "") return } price := fmt.Sprintf("%d", int(math.Ceil(obj.In.Price))) // 第1步:获取身份验证token authToken := getAuthToken() // 第2步:订单注册 orderReg := orderRegister(authToken, price, obj.Out.OrderID, obj.In.ProductID, obj.In.ProductID) orderId := strconv.Itoa(orderReg.Id) // 第3步:获取支付token paymentToken := getPaymentToken(authToken, price, orderId, obj.In.Currency) // 第4步:现金支付请求 resp := cashPay(paymentToken, obj.In.Tel) // 跳转到支付页面,以便持卡人完成支付过程 c.Redirect(http.StatusMovedPermanently, resp.Redirect_url) return } // 第1步:获取身份验证token func getAuthToken() string { info := auth_token_req{Api_Key: config.Server.PayMob.Api_Key} buf, _ := json.Marshal(info) data := string(buf) // POST请求 respBody := public.HttpPostByJson(config.Server.PayMob.Url_Auth_Token, data) log.Debug("payMob.getAuthToken 第1步,获取身份验证token! req ==> %+v resp ==> %+v", data, respBody) var resp auth_token_resp if err := json.Unmarshal([]byte(respBody), &resp); err != nil { log.Debug("%s query params err %v", "payMob.getAuthToken", err) return "" } return resp.Token } // 第2步:订单注册,返回id func orderRegister(authToken, price, orderId, name, description string) order_register_resp { var items []order_register_product items = append(items, order_register_product{ Name: name, Amount_cents: price, Description: description, Quantity: "1", }) info := order_register_req{ Auth_token: authToken, Delivery_needed: "false", Amount_cents: price, Merchant_order_id: orderId, Items: items, } buf, _ := json.Marshal(info) data := string(buf) // POST请求 respBody := public.HttpPostByJson(config.Server.PayMob.Url_Order_Register, data) log.Debug("payMob.orderRegister 第2步,订单注册,返回id! req ==> %+v resp ==> %+v", data, respBody) var resp order_register_resp if err := json.Unmarshal([]byte(respBody), &resp); err != nil { log.Debug("%s query params err %v", "payMob.orderRegister", err) return resp } return resp } // 第3步:获取支付token func getPaymentToken(authToken, price, orderId, currency string) string { info := payment_toke_req{ Auth_token: authToken, Amount_cents: price, Expiration: 3600, Order_id: orderId, Billing_data: payment_token_req_billing_data{ Apartment: "NA", Email: "test", Floor: "NA", First_name: "test", Street: "NA", Building: "NA", Phone_number: "test", Shipping_method: "NA", Postal_code: "NA", City: "NA", Country: "NA", Last_name: "test", State: "NA", }, Currency: currency, Integration_id: config.Server.PayMob.Integration_Id, } buf, _ := json.Marshal(info) data := string(buf) // POST请求 respBody := public.HttpPostByJson(config.Server.PayMob.Url_Payment_Token, data) log.Debug("payMob.getPaymentToken 第3步,获取支付token! req ==> %+v resp ==> %+v", data, respBody) var resp payment_token_resp if err := json.Unmarshal([]byte(respBody), &resp); err != nil { log.Debug("%s query params err %v", "payMob.getPaymentToken", err) return "" } return resp.Token } // 第4步:现金支付请求 func cashPay(paymentToken, tel string) cash_pay_resp { info := cash_pay_req{ Source: cash_pay_source{ Identifier: tel, Subtype: "WALLET", }, Payment_token: paymentToken, } buf, _ := json.Marshal(info) data := string(buf) // POST请求 respBody := public.HttpPostByJson(config.Server.PayMob.Url_Payment_CashPay, data) log.Debug("payMob.cashPay 第4步,现金支付请求! req ==> %+v resp ==> %+v", data, respBody) var resp cash_pay_resp if err := json.Unmarshal([]byte(respBody), &resp); err != nil { log.Debug("%s query params err %v", "payMob.cashPay", err) return resp } return resp } // 回调通知 func PayNotify(c *gin.Context) { var resp payNotify_req if err := c.ShouldBind(&resp); err != nil { log.Debug("%s query params err %v", "payMob.PayNotify", err) c.String(http.StatusOK, "") return } log.Debug("payMob.PayNotify resp ==> %+v", resp) checkContent := fmt.Sprintf("%v%v%v%v%v%v%v%v%v%v%v%v%v%v%v%v%v%v%v%v", resp.Amount_cents, resp.Created_at, resp.Currency, resp.Error_occured, resp.Has_parent_transaction, resp.Id, resp.Integration_id, resp.Is_3d_secure, resp.Is_auth, resp.Is_capture, resp.Is_refunded, resp.Is_standalone_payment, resp.Is_voided, resp.Order, resp.Owner, resp.Pending, resp.Source_data_pan, resp.Source_data_sub_type, resp.Source_data_type, resp.Success, ) hmac := public.HmacSHA512(config.Server.PayMob.HMAC, checkContent) log.Debug("payMob.PayNotify 拼接 hmac ==> %s", hmac) // 验证签名 if hmac != resp.Hmac { log.Error("payMob.PayNotify 签名失败 ==> %+v", resp) return } log.Debug("payMob.PayNotify 签名成功") // 返回码,’APPLY_SUCCESS’代表成功 if !resp.Success { log.Error("payMob.PayNotify resp ==> %+v 失败", resp) c.JSON(http.StatusOK, ret{ Code: "SUCCESS", Msg: "Success", }) return } // 数据库操作 obj := db.NewNotify(db.SP_paymob_NOTIFY) obj.In.OrderID = resp.Merchant_order_id obj.In.TradeID = strconv.Itoa(resp.Order) //obj.In.Price = resp.Amount_cents obj.DoAction(nil) // 操作成功,给道具 if obj.Out.RetCode == 1 { // 充值 resp := coreClient.Recharge(obj.Out.UserID, obj.Out.ProductID) log.Debug("%s 充值成功 %+v", "payMob.PayNotify", resp) } c.JSON(http.StatusOK, ret{ Code: "SUCCESS", Msg: "Success", }) return } // 支付完成跳转处理 func PayCallback(c *gin.Context) { c.String(http.StatusOK, "success") log.Debug("payMob.payCallback") }