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.

281 lines
12 KiB

2 years ago
package main
import (
"context"
2 years ago
"fmt"
common "git.mashibing.com/msb_47094/shopping-comm"
"github.com/asim/go-micro/plugins/registry/consul/v4"
2 years ago
"github.com/gin-gonic/gin"
2 years ago
"github.com/plutov/paypal/v4"
2 years ago
"github.com/smartwalle/alipay/v3"
"go-micro.dev/v4"
"go-micro.dev/v4/registry"
"io/ioutil"
"log"
"net/http"
2 years ago
"os"
2 years ago
"os/exec"
"payment/proto"
2 years ago
"strings"
)
// 将公钥提供给支付宝(通过支付宝后台上传)对我们请求的数据进行签名验证,我们的代码中将使用私钥对请求数据签名。
// 目前新创建的支付宝应用只支持证书方式认证,已经弃用之前的公钥和私钥的方式
// 私钥:用于加密请求参数;
// 公钥:用于解密通过 私钥加密后的 请求参数。
var (
// appId
APPID = "2021000116681444"
// 应用公钥
AliAppPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp1o6GRM72PKbU299+VmOd1527hKp+//fpEPkz7yBHBCoaAAASuIaaQyuHHtJAcjVlb4XNjLoRyIXQ71rPQaucs/5qjmvyPAlfBNJhVaUAV5ZX7WtXHMAEdTBzVODP5axjY5BSzSmpvm9fNPDuaU3ayyqENP5yoHFs2zTSpnwRoh9Ct+urqfrAJRBx435OwVJ6Abv6blKcXMSRLlgq9hM5fbzFHv7OQ8QXvrsB9NA6s2PELI5hbLFuW0T8WyX4AaFIo2SHnHGludrDwKCxO3HolwjZoQKNcsZhDOG0A3kcVUowpnP3SqkbsfVId943KxvXTIouAoYYbfD6/BKcVlC/QIDAQAB"
//支付宝公钥
AliPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhA9A6B+gV6pzSv9KKUFcqMZKrFIYOamHIeviQy6KgFuWekGG7KA6agJyGaYrogTpp97NyopgORAK+D5J7bRdcJ1smkpHlyXF0P8D9H/+wZn++1TSQYWWoPJbQXX+l0Ma42O6ISckwXHeZr0tLWUaAoTnTkSAqR0e5LtAFusND6EY/pFFJONxM2Fouwb9WiNCw6J1zQDpO1Y0bxVgQy9v19N/Qw04MtPakua2BqyZctbLggA8WhusCzbTMRZCcOXdYFajPqSvVz5278K6RGKjVeDVBUuaUcA394v1I9tHIa41o8P7j0DhFfDS5Lo8npjhkxcF2wHqfzf5NH041jwAQQIDAQAB"
//私钥
PrivateKey = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCnWjoZEzvY8ptTb335WY53XnbuEqn7/9+kQ+TPvIEcEKhoAABK4hppDK4ce0kByNWVvhc2MuhHIhdDvWs9Bq5yz/mqOa/I8CV8E0mFVpQBXllfta1ccwAR1MHNU4M/lrGNjkFLNKam+b1808O5pTdrLKoQ0/nKgcWzbNNKmfBGiH0K366up+sAlEHHjfk7BUnoBu/puUpxcxJEuWCr2Ezl9vMUe/s5DxBe+uwH00DqzY8QsjmFssW5bRPxbJfgBoUijZIeccaW52sPAoLE7ceiXCNmhAo1yxmEM4bQDeRxVSjCmc/dKqRux9Uh33jcrG9dMii4Chhht8Pr8EpxWUL9AgMBAAECggEAYsQ3QZE+Yt1bmjRUrpKSKBTSL9NICveJ75I6OffQYtXZ7fcCNS+X0qOvJhQElE8I7qUPYedNep2+CTaDUbLdxdjEShhdjENefAmN/GmKU/xw1rGMLOGaCuv7rMg6z46KHzbzhgT+zdDaag84lhnRySjE/cV8yG0qVqhFUuPjEFyMrY8lb/68P+E3P4Vm+hvdaOe10ayLmYm7YBh4Z7eSdhSxENBs+7dIG37Z2xC6FQRPm5qLrFdP03tianX71ZU/J7yky4HceqW4lIW8g4CSbWlCKewaucvnZ7q449/P/PSIbPr4KxQS8bGooQF6LGYEkRISWpYIQWBSjXvUU7PDaQKBgQDV3Hgwp93FdLU414ArdXzbklzVC3SEKdIXEBmt9s+Ec13I1xPDjM1HFezow4S/aaqi5soYyR6koVvsaXeHk+cNlphgZj6lz+p0BQvCvTrjkRFwSDdlBNuxgaiwZbjjUHZPwO42d3k2kiUwyRNcGIyDyPzo4b19D06VX2JIKdpp+wKBgQDIU8ZfQUj11Zgqx/dqd5XASGtoSQNwZPROJyLFwTMg6okgdevdoWaFgRUttPDRBhdcrtmVq7voJ35xoriKNFCSvkZc8GAVKiYgIGLXNscDKZx1EP5yc9VVbUnnTW4QXBQRB+VcLGmuh1DOPTkP+sEsTZhPM5TTMCX9HxrDtW6tZwKBgQCAlkBaGQTaTbMNC14QQ2Mgbp+MpYeYU8DzhwW5uNXLcMZqFQ/YG1fuLvu0dKLjqHgl3JiVUJAxMqgfvMZW6ZIadHsIM1Hlxt7UhZgtrjOzUq1mkrVj8wjZcPlpnrANVXrdt0ZDz5A9RKBB9hTC4ivSrU2MBPc3M7XvUFu6wheGcwKBgQCCMCeIOiZPVWuZyfDZ6TOSDb53vJOWlJVMwRRRDljK+ID7bodFtqGo+5Wm6aNjRCEko6FWKpBotFnxQb3KW2tNooiZ18Gpn4W9dS6nDLtTK9S5I70o5mxrIyZXQrPXv+9ujgIZ3+cifGAgWBtgbibiQt9MAYqjoPPfRzqem6d82wKBgQCjcqFOK7Ff0bSz6S2PzFLWyHBlrEKXI+9+9N5nS8aFB8uJduu0PqK4CXs6FqbY+6xuZ9Qdhe9j2NXoqZoJyQlb8/aL1etT+/JP0Md9Wi0v9SVnnz6Ci1RmJEjO02Q/xrpphEbK87h7YpNUI4flHR4ZCr9EmXqdXRTuXImUImc3uw=="
ApliClient, _ = alipay.New(APPID, PrivateKey, false)
FindOrderClient = proto.NewFindOrderService("", nil)
UpdateTraderClient = proto.NewUpdateTradeOrderService("", nil)
2 years ago
//PayPal国际支付
PayPalClientID = "AX5c8C-Z9P5vXgs22Q3MWKaEKvVa5-vtU3jtNrQe8W2s-x8eXYn_2aA-e4paaHo6I0Z9eba0Ur2LTdZI"
PayPalPublicKey = ""
PayPalSecretID = "EB_svAAyczD2OoCMh2HMA4ApBysCbHli8gOpFUfKLOaI5zkoePeNd54OI1PT5yDtAqNsWgho7IYNdqFR"
//真实环境 paypal.APIBaseLive
PaypalClient, _ = paypal.NewClient(PayPalClientID, PayPalSecretID, paypal.APIBaseSandBox)
2 years ago
)
// 初始化的init
func init() {
2 years ago
//PayPal国际支付
//PaypalClient, _ = paypal.NewClient(PayPalClientID, PayPalSecretID, paypal.APIBaseSandBox)
PaypalClient.SetLog(os.Stdout) // Set log to terminal stdout
accessToken, err := PaypalClient.GetAccessToken(context.Background())
fmt.Println("PayPal国际支付 :\n", accessToken, " \n ", err)
//支付宝支付
2 years ago
ApliClient.LoadAppPublicCert(AliAppPublicKey)
ApliClient.LoadAliPayPublicCert(AliPublicKey)
//证书的方式 ApliClient.LoadAliPayRootCert()
//注册中心
consulReg := consul.NewRegistry(func(options *registry.Options) {
options.Addrs = []string{common.ConsulReistStr}
})
rpcServer := micro.NewService(
micro.Name("shop-payment"),
micro.Registry(consulReg),
)
FindOrderClient = proto.NewFindOrderService("trade-order", rpcServer.Client())
UpdateTraderClient = proto.NewUpdateTradeOrderService("trade-order", rpcServer.Client())
2 years ago
}
func TradeWapPayPal(c *gin.Context) {
//order, err := PaypalClient.CreateOrder(paypal.OrderIntentCapture, []paypal.PurchaseUnitRequest{paypal.PurchaseUnitRequest{ReferenceID: "ref-id", Amount: paypal.Amount{Total: "7.00", Currency: "USD"}}})
2 years ago
}
// 手机端的支付 弹出选择APP 还是 H5
func TradeWapAliPay(c *gin.Context) {
fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TradeAppAliPay ")
var pay = alipay.TradeWapPay{}
pay.TotalAmount = c.Query("payAmount")
pay.OutTradeNo = c.Query("orderNo")
2 years ago
//支付之后 支付宝回调的API
//pay.ReturnURL = "http://127.0.0.1:8086/return"
2 years ago
pay.NotifyURL = "http://j8utmw.natappfree.cc/return"
pay.Body = "APP订单"
2 years ago
pay.Subject = "商品标题"
res, err := ApliClient.TradeWapPay(pay)
if err != nil {
fmt.Println("支付失败 :", err)
}
payURL := res.String()
payURL = strings.Replace(payURL, "&", "^&", -1)
exec.Command("cmd", "/c", "start", payURL).Start()
}
// 网站页面扫码支付
func TradePageAlipay(c *gin.Context) {
fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TradePageAlipay ")
var p = alipay.TradePagePay{}
2 years ago
p.NotifyURL = "http://j8utmw.natappfree.cc/return" //支付异步
2 years ago
//p.ReturnURL = "http://127.0.0.1:8086/return" //同步
p.Subject = "商品支付"
p.OutTradeNo = c.Query("orderNo")
p.TotalAmount = c.Query("payAmount")
2 years ago
p.ProductCode = "FAST_INSTANT_TRADE_PAY["
2 years ago
res, err := ApliClient.TradePagePay(p)
if err != nil {
fmt.Println("支付失败 :", err)
}
payURL := res.String()
payURL = strings.Replace(payURL, "&", "^&", -1)
exec.Command("cmd", "/c", "start", payURL).Start()
}
// 回调函数
/*
gmt_create=2022-11-17+13%3A39%3A42&
charset=utf-8&
gmt_payment=2022-11-17+13%3A39%3A48&
notify_time=2022-11-17+13%3A39%3A49&
subject=%E4%BF%AE%E6%AD%A3%E4%BA%86%E4%B8%AD%E6%96%87%E7%9A%84+Bug&
sign=Q%2FqJv73maQ45zEdJfYfce9%2FeCDYx03otzJL67wetT1q%2Ft1vrVrpf8EHDpDQxKzcchDqOJ%2B1v3lDyhHwd4KUHd3z9APw%2BGzonHYgccuLNwEwaYQ8Pv7PjzFMOvS2HiHptUdYMWFXKHnYi3AE%2FuBtxGASljBuMms9jnABf1xFM4BVVhdmtSdMtlhbJ0eDNNs0pAs1tdCXdX%2FV6j%2BWi6GSU7VYMRzhzhlWYm%2FTSZao4QNqjkoY6j1G4MWx%2Fvmyk3SgItDSEpECxzO2Vt0F0slbTUJwqllkQ%2Fk323VvXFBHxHOxltpnrZfegYK%2B0mE4jcpQ9jRCnXRCDMHKI9adl6kJX9A%3D%3D&
buyer_id=2088622955228317&
invoice_amount=10.00&
version=1.0&
notify_id=2022111700222133949028310528415537&
fund_bill_list=%5B%7B%22amount%22%3A%2210.00%22%2C%22fundChannel%22%3A%22ALIPAYACCOUNT%22%7D%5D&
notify_type=trade_status_sync&
out_trade_no=2022-11-17+13%3A39%3A33.8566275+%2B0800+CST+m%3D%2B3.273247501&
total_amount=10.00&
trade_status=TRADE_SUCCESS&
trade_no=2022111722001428310502276237&
auth_app_id=2021000116681444&
receipt_amount=10.00&
point_amount=0.00&
app_id=2021000116681444&
buyer_pay_amount=10.00&
sign_type=RSA2&
seller_id=2088621954959062
2 years ago
*/
func AliPayNotify(c *gin.Context) {
fmt.Println(" >>>>>>>>>>>>>>>>> AliPayNotify >>>>>>>>>>>>>>>>>")
//获取请求报文的长度
//conLen := c.Request.ContentLength
////新建一个字节切片 长度
//body := make([]byte, conLen)
//n, _ := c.Request.Body.Read(body)
//改进读取的方法
data, _ := ioutil.ReadAll(c.Request.Body)
vals := string(data[0:len(data)])
2 years ago
fmt.Println(vals)
//验证是否支付成功
if strings.Contains(vals, "TRADE_SUCCESS") {
kv := strings.Split(vals, "&")
var no string
for k, v := range kv {
fmt.Println(k, ":", v)
//out_trade_no=xxxx
if strings.HasPrefix(v, "out_trade_no") {
index := strings.Index(v, "=")
no = v[index+1 : len(v)]
2 years ago
}
}
fmt.Println("订单:", no, "成功支付")
//远程调用 服务
//查询订单详情
req := &proto.FindOrderReq{}
//req.Id =
req.OrderNo = no
obj, err := FindOrderClient.FindOrder(context.TODO(), req)
if err != nil {
log.Println("findOrder err :", err)
//common.RespFail(c.Writer, resp, "查询失败")
}
fmt.Println("findOrder:", obj)
//c.JSON(http.StatusOK, gin.H{"findOrder": "SUCCESS", "Message": obj})
//修改订单
reqUpdate := &proto.AddTradeOrderReq{}
tradeOrder := &proto.TradeOrder{}
tradeOrder.ID = obj.TradeOrder.ID
reqUpdate.TradeOrder = tradeOrder
//订单状态1待支付2已关闭3已支付4已发货5已收货6已完成7已追评
reqUpdate.TradeOrder.OrderStatus = 3
_, err = UpdateTraderClient.UpdateTradeOrder(context.TODO(), reqUpdate)
if err != nil {
log.Println("/UpdateTradeOrder err ", err)
return
}
c.JSON(http.StatusOK, gin.H{"reslut": "SUCCESS", "Message": "修改订单支付成功!"})
2 years ago
}
}
2 years ago
// 生成收款订单
func CreateOrderPayer(c *gin.Context) {
purchaseUnits := make([]paypal.PurchaseUnitRequest, 1)
purchaseUnits[0] = paypal.PurchaseUnitRequest{
Amount: &paypal.PurchaseUnitAmount{
Currency: "USD", //收款类型
Value: c.Query("amount"), //收款数量
},
InvoiceID: c.Query("orderNo"),
ReferenceID: "123",
Description: "商品支付",
}
payer := &paypal.CreateOrderPayer{
Name: &paypal.CreateOrderPayerName{
//GivenName: user_idStr,
//Surname: user_idStr,
},
}
appContext := &paypal.ApplicationContext{
ReturnURL: "http://j8utmw.natappfree.cc/payPalBack?orderNo=" + c.Query("orderNo"), //回调链接
}
//CreateOrder(ctx context.Context, intent string, purchaseUnits []PurchaseUnitRequest, payer *CreateOrderPayer, appContext *ApplicationContext)
orderResponse, err := PaypalClient.CreateOrder(context.Background(), "CAPTURE", purchaseUnits, payer, appContext)
if err != nil {
log.Println("create order errors:", err)
c.JSON(http.StatusNotExtended, gin.H{"reslut": err, "Message": "构建订单失败!", "CODE": http.StatusNotExtended})
return
}
//c.Header("ID", orderResponse.ID)
payURL := (*orderResponse).Links[1].Href
payURL = strings.Replace(payURL, "&", "^&", -1)
common.SetUserToken()
//https://www.sandbox.paypal.com/checkoutnow?token=85V82337B3775564V
exec.Command("cmd", "/c", "start", payURL).Start()
//(*order).Links[1].Href就是支付的链接
}
// 回调(可以利用上面的回调链接实现)
// https://www.sandbox.paypal.com/webapps/hermes?
// flow=1-P&ulReturn=true&
// token=85V82337B3775564V&
// rcache=2&
// useraction=CONTINUE&
// cookieBannerVariant=1&
// targetService4174=xorouternodeweb&country.x=C2&
// locale.x=zh_XC
func PaypalCallback(c *gin.Context) {
//c, err := paypal.NewClient(clientID, secretID, paypal.APIBaseSandBox)
//if err != nil {
// return err
//}
//_, err = c.GetAccessToken()
//if err != nil {
// return err
//}
//“status”:“COMPLETED 或者 PENDING” 说明支付成功了
ctor := paypal.CaptureOrderRequest{}
//CaptureOrder(ctx context.Context, orderID string, captureOrderRequest CaptureOrderRequest)
order, err := PaypalClient.CaptureOrder(context.Background(), c.Query("ID"), ctor)
o, _ := PaypalClient.GetOrder(context.Background(), c.Query("ID"))
log.Println(o, "\n", order)
if err != nil {
log.Println("/UpdateTradeOrder err ", err)
//return
}
//查看回调完成后订单状态是否支付完成。
if (*order).Status != "COMPLETED" {
log.Println("/UpdateTradeOrder err ", err)
c.JSON(http.StatusNotExtended, gin.H{"reslut": err, "Message": "订单回调失败!", "CODE": http.StatusNotExtended})
return
}
c.JSON(http.StatusOK, gin.H{"reslut": "SUCCESS", "Message": "修改订单支付成功!"})
}
2 years ago
func main() {
r := gin.Default()
2 years ago
r.SetTrustedProxies([]string{common.QSIp})
2 years ago
r.GET("/appPay", TradeWapAliPay)
r.GET("/pagePay", TradePageAlipay)
r.POST("/return", AliPayNotify)
2 years ago
//payPal
r.GET("/payPal", CreateOrderPayer)
r.GET("/payPalBack", PaypalCallback)
2 years ago
r.Run(":8086")
}