package pay import ( "yunyan/comm" "yunyan/pb" "yunyan/utils" ) // @Summary 处理PayPal支付异步通知 [内部RPC] // @Description 接收由HTTP回调网关转发来的已验证的支付通知,并处理业务逻辑 // @Tags Pay // @Accept json // @Produce json // @Security BearerAuth // @Param notify body pb.PayPayPalNotifyReq true "PayPal 异步通知参数" // @Success 200 {object} comm.HttpResult "处理结果" // @Router /api/home/pay_paypalnotify [post] func (this *apiComp) PayPalNotify(session comm.IUserSession, req *pb.PayPayPalNotifyReq) (resp []byte, errdata *pb.ErrorData) { // var ( // ok bool // model *pb.DBPayOrder // err error // ) // headers := map[string]string{ // "PayPal-Transmission-Id": req.TransmissionId, // "PayPal-Transmission-Time": req.TransmissionTime, // "PayPal-Cert-Url": req.CertUrl, // "PayPal-Auth-Algo": req.AuthAlgo, // "PayPal-Transmission-Sig": req.TransmissionSig, // "Webhook-Id": req.WebhookId, // } // // 验签(当前为骨架实现,返回 true) // if ok, err = paypal.VerifyWebhook(headers, []byte(req.Body)); !ok || err != nil { // errdata = &pb.ErrorData{ // Code: pb.ErrorCode_PayNotifyDecryptFail, // Message: "验证PayPal通知失败:" + fmt.Sprintf("%v", err), // } // return // } // // 解析通知body // var body map[string]any // if err = json.Unmarshal([]byte(req.Body), &body); err != nil { // resp = []byte(utils.ToString(map[string]string{ // "code": "Fail", // "message": "通知体解析失败", // })) // return // } // // 仅处理支付成功事件 // if eventType, _ := body["event_type"].(string); eventType != "PAYMENT.CAPTURE.COMPLETED" { // resp = []byte(utils.ToString(map[string]string{ // "code": "SUCCESS", // "message": "忽略非支付完成事件", // })) // return // } // var outTradeNo string // if resourceAny, ok := body["resource"]; ok { // if resource, ok := resourceAny.(map[string]any); ok { // // 优先读取 custom_id(我们在下单时写入了商户订单号) // if v, ok := resource["custom_id"].(string); ok { // outTradeNo = v // } // // 备选:purchase_units[0].reference_id(若事件为订单层通知) // if outTradeNo == "" { // if puAny, ok := resource["purchase_units"]; ok { // if pus, ok := puAny.([]any); ok && len(pus) > 0 { // if unit, ok := pus[0].(map[string]any); ok { // if ref, ok := unit["reference_id"].(string); ok { // outTradeNo = ref // } // } // } // } // } // // 备选:invoice_id // if outTradeNo == "" { // if v, ok := resource["invoice_id"].(string); ok { // outTradeNo = v // } // } // } // } // if outTradeNo == "" { // resp = []byte(utils.ToString(map[string]string{ // "code": "Fail", // "message": "无法识别订单号", // })) // return // } // // 查询并更新订单状态 // if model, err = this.module.model.getPayOrder(outTradeNo); err != nil { // resp = []byte(utils.ToString(map[string]string{ // "code": "Fail", // "message": fmt.Sprintf("订单不存在: %s", outTradeNo), // })) // return // } // if model.Status != pb.PayOrderStatus_PAY_ORDER_PENDING { // resp = []byte(utils.ToString(map[string]string{ // "code": "SUCCESS", // "message": "成功", // })) // return // } // // 标记已支付并下发资源 // model.Status = pb.PayOrderStatus_PAY_ORDER_PAID // if err = this.deliverResourceByOrder(model); err != nil { // resp = []byte(utils.ToString(map[string]string{ // "code": "Fail", // "message": fmt.Sprintf("发货资源失败: %v", err), // })) // return // } // if err = this.module.model.updatePayOrder(model); err != nil { // resp = []byte(utils.ToString(map[string]string{ // "code": "Fail", // "message": fmt.Sprintf("更新订单状态失败: %v", err), // })) // return // } resp = []byte(utils.ToString(map[string]string{ "code": "SUCCESS", "message": "成功", })) return }