package cropay import ( "encoding/base64" "encoding/xml" "fmt" "net/http" "net/url" "strconv" "strings" "time" "bet24.com/servers/payment/shop" "bet24.com/log" "bet24.com/public" coreClient "bet24.com/servers/coreservice/client" "bet24.com/servers/payment/config" "bet24.com/servers/payment/db" "github.com/gin-gonic/gin" uuid "github.com/satori/go.uuid" ) // 下单 func Order(c *gin.Context) { obj := db.NewOrder(db.SP_CRO_ORDER) if err := c.ShouldBind(&obj.In); err != nil { log.Debug("%s query params err %v", "cropay.Order", 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", "cropay.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", "cropay.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", "cropay.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", "cropay.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", "cropay.Order", obj.In) c.String(http.StatusOK, "") return } id, _ := uuid.NewV4() order_hash := config.Server.Cropay.Order_hash merchant_id := config.Server.Cropay.Merchant_id merch_order_id := obj.Out.OrderID price_currency := "IDR" price_amount := obj.In.Price //order_hash + merchant_id + merch_order_id + price_currency + price_amount checkContent := order_hash + strconv.Itoa(merchant_id) + merch_order_id + price_currency + strconv.FormatFloat(price_amount, 'f', -1, 64) log.Debug("order.checkContent ==> %s", checkContent) signature := public.GetMd5String(checkContent) //请求payOrder的代码 req := payOrder_req{ baseInfo: baseInfo{ Merchant_id: merchant_id, Order_type: "5", Gw_version: "go(1.0)", Language: "", Merch_order_ori_id: obj.Out.OrderID, Merch_order_id: obj.Out.OrderID, Merch_order_date: time.Now().Format("20060102150405"), Price_currency: price_currency, Price_amount: price_amount, Ip: obj.In.IpAddress, Url_sync: config.Server.Cropay.Url_sync, Url_succ_back: config.Server.Cropay.Url_succ_back, Url_fail_back: config.Server.Cropay.Url_fail_back, Url_referrer_domain: config.Server.Cropay.Url_referrer_domain, }, billInfo: billInfo{ Bill_address: "", Bill_country: "", Bill_province: "", Bill_city: "", Bill_email: obj.In.Email, Bill_phone: obj.In.Tel, Bill_post: "", }, deliveryInfo: deliveryInfo{ Delivery_name: obj.In.Name, Delivery_address: "", Delivery_country: "", Delivery_province: "", Delivery_city: "", Delivery_email: obj.In.Email, Delivery_phone: obj.In.Tel, Delivery_post: "", }, productInfo: productInfo{ Product_name: "Recharge", Product_sn: obj.In.ProductID, Quantity: 1, Unit: obj.In.Price, }, Signature: signature, Client_finger_cybs: id.String(), } params := url.Values{} params.Set("merchant_id", strconv.Itoa(config.Server.Cropay.Merchant_id*818+5201314)) params.Set("order_type", req.Order_type) params.Set("gw_version", req.Gw_version) params.Set("language", req.Language) params.Set("merch_order_ori_id", req.Merch_order_ori_id) params.Set("merch_order_id", req.Merch_order_id) params.Set("merch_order_date", req.Merch_order_date) params.Set("price_currency", req.Price_currency) params.Set("price_amount", strconv.FormatFloat(req.Price_amount, 'f', -1, 64)) params.Set("ip", req.Ip) params.Set("url_sync", req.Url_sync) params.Set("url_succ_back", req.Url_succ_back) params.Set("url_fail_back", req.Url_fail_back) params.Set("url_referrer_domain", req.Url_referrer_domain) params.Set("bill_address", req.Bill_address) params.Set("bill_country", req.Bill_country) params.Set("bill_province", req.Bill_province) params.Set("bill_city", req.Bill_city) params.Set("bill_email", req.Bill_email) params.Set("bill_phone", req.Bill_phone) params.Set("bill_post", req.Bill_post) params.Set("delivery_name", req.Delivery_name) params.Set("delivery_address", req.Delivery_address) params.Set("delivery_country", req.Delivery_country) params.Set("delivery_province", req.Delivery_province) params.Set("delivery_city", req.Delivery_city) params.Set("delivery_email", req.Delivery_email) params.Set("delivery_phone", req.Delivery_phone) params.Set("delivery_post", req.Delivery_post) params.Set("product_name", req.Product_name) params.Set("product_sn", req.Product_sn) params.Set("quantity", strconv.Itoa(req.Quantity)) params.Set("unit", strconv.FormatFloat(req.Unit, 'f', -1, 64)) params.Set("signature", req.Signature) params.Set("client_finger_cybs", req.Client_finger_cybs) respBody := public.HttpPostForm(config.Server.Cropay.Url_pay_order, params) log.Debug("cropay.payOrder req ==> %+v resp ==> %+v", params, respBody) var resp payOrder_resp if err := xml.Unmarshal([]byte(respBody), &resp); err != nil { log.Error("cropay xml unmarshal req ==> %+v resp ==> %+v fail %v", params, respBody, err) return } log.Debug("cropay.payOrder resp ==> %+v", resp) //md5(order_hash+merchant_id+merch_order_id+price_currency+price_amount+order_id+status) checkContent_resp := config.Server.Cropay.Order_hash + strconv.Itoa(resp.Merchant_id) + resp.Merch_order_id + resp.Price_currency + strconv.FormatFloat(resp.Price_amount, 'f', -1, 64) + resp.Order_id + resp.Status // 生成签名 signature_resp := public.GetMd5String(checkContent_resp) if resp.Signature != signature_resp { log.Error("cropay.payOrder 签名失败 post return resp ==> %+v", resp) return } log.Debug("cropay.payOrder 签名成功") // 待处理状态 if resp.Status != "T" { log.Error("cropay.payOrder post return resp fail ==> %+v", resp) c.JSON(http.StatusOK, struct { Status string `json:"status"` Message string `json:"message"` Merch_order_id string `json:"merch_order_id"` Order_id string `json:"order_id"` Price_currency string `json:"price_currency"` Price_amount float64 `json:"price_amount"` }{ Status: resp.Status, Message: resp.Message, Merch_order_id: req.Merch_order_id, Order_id: resp.Order_id, Price_currency: resp.Price_currency, Price_amount: resp.Price_amount, }) return } paymentUrl, err := base64.StdEncoding.DecodeString(resp.Payment_url) if err != nil { log.Error("cropay.payOrder response Payment_url DecodeString fail %v", err) return } log.Debug("paymentUrl ==> %s", string(paymentUrl)) // 跳转到支付页面,以便持卡人完成支付过程 c.Redirect(http.StatusMovedPermanently, string(paymentUrl)) return } // 回调通知 func Notify(c *gin.Context) { var resp notify_resp if err := c.ShouldBind(&resp); err != nil { log.Debug("%s query params err %v", "cropay.Notify", err) c.String(http.StatusOK, "") return } log.Debug("cropay.Notify resp ==> %+v", resp) // order_hash+merchant_id+merch_order_id+price_currency+price_amount+order_id+status checkContent := config.Server.Cropay.Order_hash + strconv.Itoa(resp.Merchant_id) + resp.Merch_order_id + resp.Price_currency + resp.Price_amount + resp.Order_id + resp.Status signature := public.GetMd5String(checkContent) if resp.Signature != signature { log.Error("cropay.Notify 签名失败 resp ==> %+v", resp) c.String(http.StatusOK, "") c.Redirect(http.StatusMovedPermanently, config.Server.Cropay.Url_resultPay) return } log.Debug("cropay.Notify 签名成功") if resp.Status != "Y" { log.Error("cropay.Notify resp ==> %+v 失败", resp) c.Redirect(http.StatusMovedPermanently, config.Server.Cropay.Url_resultPay) return } //price, err := strconv.Atoi(strings.ReplaceAll(resp.Price_amount, ".00", "")) //if err != nil { // log.Error("cropay.Notify price_amount format err %v", err) // c.Redirect(http.StatusMovedPermanently, config.Server.Cropay.Url_resultPay) // return //} // 数据库操作 obj := db.NewNotify(db.SP_CRO_NOTIFY) obj.In.OrderID = resp.Merch_order_id obj.In.TradeID = resp.Order_id //obj.In.Price = price obj.DoAction(nil) //操作成功,给道具 if obj.Out.RetCode == 1 { //充值 resp := coreClient.Recharge(obj.Out.UserID, obj.Out.ProductID) log.Debug("%s 充值成功 %+v", "cropay.Notify", resp) } c.String(http.StatusOK, "ISRESPONSION") c.Redirect(http.StatusMovedPermanently, fmt.Sprintf("%s?code=%d&order=%s", config.Server.Cropay.Url_resultPay, obj.Out.RetCode, resp.Order_id)) return } // 成功回调 func Succ(c *gin.Context) { var resp notify_resp if err := c.ShouldBind(&resp); err != nil { log.Debug("%s query params err %v", "cropay.Succ", err) c.String(http.StatusOK, "") return } log.Debug("cropay.Succ resp ==> %+v", resp) c.Redirect(http.StatusMovedPermanently, fmt.Sprintf("%s?code=%d&order=%s", config.Server.Cropay.Url_resultPay, 1, resp.Order_id)) } // 失败回调 func Fail(c *gin.Context) { var resp notify_resp if err := c.ShouldBind(&resp); err != nil { log.Debug("%s query params err %v", "cropay.Fail", err) c.String(http.StatusOK, "") return } log.Debug("cropay.Fail resp ==> %+v", resp) c.Redirect(http.StatusMovedPermanently, config.Server.Cropay.Url_resultPay) }