GO語言支付寶沙箱對接的實現(xiàn)
1.1 官網(wǎng)
沙箱官網(wǎng):
https://open.alipay.com/develop/sandbox/app
秘鑰用具下載:
https://opendocs.alipay.com/common/02kipk?pathHash=0d20b438
1.2 秘鑰生成(系統(tǒng)默認)
1.3 秘鑰生成(軟件生成)
- 點擊生成密鑰
- 生成成功
- 自定義密鑰
****
- 復(fù)制粘貼之前生成的公鑰并點擊保存
- 繼續(xù)點擊確認
1.4 golan 安裝 SDK
go get -u github.com/smartwalle/alipay/v3
1.5 GoLand 代碼
- app
- utils
- abfPay.go
- utils
package utils import ( "fmt" "github.com/smartwalle/alipay/v3" "net/url" ) func ZfbPay(orderID string, totalPrice string) string { appID := "9021000131612134" // 你的appID privateKey := "" // 你的私鑰 aliPublicKey := "" // 支付寶的公鑰 var client, err = alipay.New(appID, privateKey, false) if err != nil { panic(err) } err = client.LoadAliPayPublicKey(aliPublicKey) if err != nil { panic(err) } //var p = alipay.TradeWapPay{} var p = alipay.TradePagePay{} p.NotifyURL = "http://192.168.137.188:5173/#/pages/pay-success/pay-success" //支付寶回調(diào) p.ReturnURL = "http://192.168.137.188:5173/#/pages/pay-success/pay-success" //支付后調(diào)轉(zhuǎn)頁面 p.Subject = "云尚校園-訂單支付" //標題 p.OutTradeNo = orderID //傳遞一個唯一單號 p.TotalAmount = totalPrice //金額 //p.ProductCode = "QUICK_WAP_WAY" p.ProductCode = "FAST_INSTANT_TRADE_PAY" //網(wǎng)頁支付 var url2 *url.URL url2, err = client.TradePagePay(p) if err != nil { fmt.Println(err) } var payURL = url2.String() println(payURL) return payURL }
- app
- dto
- Pay.go
- dto
package dto type ShopPay struct { ByCode string `json:"byCode"` ShopID string `json:"id"` OrderTips string `json:"tips"` OrderTotalPrice string `json:"totalPrice"` OrderStatus string `json:"status"` OrderID string `json:"order_id"` }
- app
- model
- Pay.go
- model
package models import "gorm.io/gorm" // // ShopPay // @Description: 生成訂單號 // type ShopPay struct { gorm.Model ByCode string `gorm:"type:varchar(100)"` OrderId string `gorm:"type:varchar(100); unique;not null"` // 訂單ID OrderStatus string `gorm:"type:varchar(100); not null"` // 訂單狀態(tài) OrderTips string `gorm:"type:varchar(200); not null"` // 訂單備注 OrderTotalPrice string `gorm:"type:varchar(100); not null"` ShopID string `gorm:"type:varchar(100); not null"` }
- app
- common
- databaseMySQL.go
- common
package common import ( "github.com/spf13/viper" "gorm.io/driver/mysql" "gorm.io/gorm" ) var DB *gorm.DB func InitDB() *gorm.DB { host := viper.GetString("datasource.host") port := viper.GetString("datasource.port") database := viper.GetString("datasource.database") username := viper.GetString("datasource.username") password := viper.GetString("datasource.password") charset := viper.GetString("datasource.charset") db, err := gorm.Open(mysql.Open(username+`:`+password+`@tcp(`+host+`:`+port+`)/`+database+`?charset=`+charset+`&parseTime=true&loc=Local`), &gorm.Config{}) if err != nil { panic("failed to connect database, err: " + err.Error()) } db.AutoMigrate(&model.ShopPay{}) DB = db return db } func GetDB() *gorm.DB { return DB }
- app
- config
- application.yml
- config
server: port: 9999 datasource: diverName: mysql host: 127.0.0.1 port: 3306 database: go-app username: root password: 123456 charset: utf8
- app
- controller
- PayController.go
- controller
package controller import "github.com/gin-gonic/gin" type PayController interface { AddShopPay(ctx *gin.Context) OrderPay(ctx *gin.Context) }
- app
- controller
- pay
- pay.go
- pay
- controller
package pay import ( "github.com/gin-gonic/gin" "go-app/common" "go-app/controller" "go-app/dto" model "go-app/models" "go-app/response" "go-app/utils" "gorm.io/gorm" "strconv" ) type PayFun interface { controller.PayController } type payDB struct { DB *gorm.DB } func PayFunction() PayFun { db := common.GetDB() db.AutoMigrate(model.User{}) return payDB{DB: db} } func (db payDB) AddShopPay(ctx *gin.Context) { getPayData := dto.ShopPay{} ctx.BindJSON(&getPayData) getPayData.OrderStatus = "2" getPayData.OrderID = strconv.FormatInt(utils.GetSnowflakeId(), 10) if getPayData.ByCode != "" { db.DB.Debug().Create(&getPayData) } response.Success(ctx, gin.H{"data": getPayData}, "success") } func (db payDB) OrderPay(ctx *gin.Context) { order := model.ShopPay{} id, _ := strconv.Atoi(ctx.Params.ByName("orderID")) db.DB.Debug().Where("order_id", id).First(&order) pay := utils.ZfbPay(order.OrderId, order.OrderTotalPrice) response.Success(ctx, gin.H{"data": pay}, "success") }
- app
- router.go
package main import ( "github.com/gin-gonic/gin" shopController "go-app/controller/shop" ) func CollectRoute(r *gin.Engine) *gin.Engine { // 支付頁面 payGroup := r.Group("api/pay/") payFun := payController.PayFunction() payGroup.POST("/AddShopPay/", payFun.AddShopPay) payGroup.POST("/orderPay/:orderID", payFun.OrderPay) return r }
- app
- main.go
package main import ( "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" "github.com/spf13/viper" "go-app/common" "os" ) func main() { InitConfig() common.InitDB() r := gin.Default() config := cors.DefaultConfig() config.AllowAllOrigins = true //允許所有域名 config.AllowMethods = []string{"GET", "POST", "OPTIONS"} //允許請求的方法 config.AllowHeaders = []string{"token", "tus-resumable", "upload-length", "upload-metadata", "cache-control", "x-requested-with", "*"} r.Use(cors.New(config)) // 定義路由和處理函數(shù) r = CollectRoute(r) port := viper.GetString("server.port") if port != "" { panic(r.Run(":" + port)) } r.Run() } func InitConfig() { workDir, _ := os.Getwd() viper.SetConfigName("application") viper.SetConfigType("yml") viper.AddConfigPath(workDir + "/config") err := viper.ReadInConfig() if err != nil { panic(err) } }
1.6 前端代碼
<template> <view> <!-- 自定義導(dǎo)航欄 --> <view class="box-bg" style="font-size: 36rpx;"> <!-- <uni-nav-bar shadow left-icon="left" right-icon="cart" title="購物車" /> --> <uni-nav-bar shadow fixed="true" left-icon="left" right-text="關(guān)閉" title="支付訂單" statusBar="true" @clickLeft="backCommitShop" @clickRight="colsePay" /> </view> <!-- 支付選擇模塊 --> <view class="pay-main"> <radio-group name=""> <label> <view class="pay-item"> <view v-for="(item,index) in payItemIamges.data" :key="index"> <view class="pay-connect"> <img class="pay-item-image" :src="item.imageUrl" alt=""> <view class="pay-item-text"> <view class="pay-item-text-top">{{item.nameFather}}</view> <view class="pay-item-text-foot">{{item.name}}</view> </view> <label class="pay-radio"> <radio :checked="isChecked" color="#F33" /><text></text> </label> </view> </view> </view> </label> </radio-group> </view> <!-- 底部去支付模塊 --> <view class="foot-pay"> <view class="total-pay"> <view class="total">合計:</view> <view class="total">¥{{payMoney}}</view> </view> <view class="go-pay" @tap="goPay">去支付</view> </view> </view> </template> <script setup> import { onLoad, } from '@dcloudio/uni-app'; import { reactive, ref } from "vue" import {orderPay} from "@/api/shop/pay.js" onLoad((e) => { // 獲取價格 payMoney.value = e.price; // 獲取訂單號 orderID.value = e.orderID; }) // 選擇支付方式 const isChecked = ref(false); const payItemIamges = reactive({ data: [{ nameFather: "微信支付", name: "推薦微信用戶使用", imageUrl: "http://s1jh1gxy3.hn-bkt.clouddn.com/shopCartCommit/wPay.png" }, { nameFather: "支付寶支付", name: "推薦支付寶用戶使用", imageUrl: "http://s1jh1gxy3.hn-bkt.clouddn.com/shopCartCommit/zPay.png" } ] }) // 獲取金額 const payMoney = ref(0); // 訂單ID const orderID = ref(0); // 去支付 const goPay = () => { uni.navigateTo({ url:"@/pages/pay-success/pay-success" }) orderPay(orderID.value).then(res=>{ //#ifdef APP-PLUS plus.runtime.openURL(res.data.data, function(res){ console.log(res); }) //#endif // #ifdef H5 window.open(res.data.data) // #endif }) } const backCommitShop = () => { uni.navigateBack({ delta: 1 }) } const colsePay = () => { uni.navigateTo({ url: "../shop-commit/shop-commit" }) } </script> <style lang="less" scoped> // 底部樣式 .foot-pay { border-top: 2rpx solid #fcc; line-height: 100rpx; height: 100rpx; width: 100%; position: fixed; bottom: 0; left: 0; display: flex; justify-content: space-between; align-items: center; .total-pay { display: flex; flex: 1; background-color: black; color: white; padding-left: 120rpx; .total { padding: 0rpx 7rpx; } } .go-pay { padding: 0rpx 100rpx; color: white; background-color: #49BDFB; } } // 支付樣式 .pay-main { margin-top: 15rpx; .pay-item { .pay-connect { display: flex; justify-content: space-between; padding: 20rpx 30rpx; border-bottom: 8rpx solid #F5F5F5; .pay-item-image { width: 100rpx; height: 100rpx; } .pay-item-text { flex: 1; padding-left: 80rpx; .pay-item-text-top { font-weight: bold; } .pay-item-text-foot { color: #636263; } } .pay-radio { padding-top: 20rpx; } } } } .box-bg { background-color: #F5F5F5; padding: 0 5px 0; } ::v-deep uni-text.uni-nav-bar-text.uni-ellipsis-1 { font-size: 34rpx; font-weight: bolder; } ::v-deep uni-text.uni-nav-bar-right-text { font-size: 32rpx; font-weight: bolder; } pay-item-text { flex: 1; padding-left: 80rpx; .pay-item-text-top { font-weight: bold; } .pay-item-text-foot { color: #636263; } } .pay-radio { padding-top: 20rpx; } } } } .box-bg { background-color: #F5F5F5; padding: 0 5px 0; } ::v-deep uni-text.uni-nav-bar-text.uni-ellipsis-1 { font-size: 34rpx; font-weight: bolder; } ::v-deep uni-text.uni-nav-bar-right-text { font-size: 32rpx; font-weight: bolder; } </style>
到此這篇關(guān)于GO語言支付寶沙箱對接的實現(xiàn)的文章就介紹到這了,更多相關(guān)GO語言支付寶沙箱對接內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang 函數(shù)執(zhí)行時間統(tǒng)計裝飾器的一個實現(xiàn)詳解
這篇文章主要介紹了Golang 函數(shù)執(zhí)行時間統(tǒng)計裝飾器的一個實現(xiàn)詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-03-03Golang timer可能造成的內(nèi)存泄漏問題分析
本文探討了Golang中timer可能造成的內(nèi)存泄漏問題,通過分析一段代碼,解釋了為什么協(xié)程在調(diào)用timer.Stop()后無法正常退出,文章指出,timer.Stop()并不關(guān)閉Channel,導(dǎo)致協(xié)程無法繼續(xù)執(zhí)行,最后,提出了一種修復(fù)方法,并呼吁大家關(guān)注和分享2024-12-12go讀取request.Body內(nèi)容踩坑實戰(zhàn)記錄
很多初學(xué)者在使用Go語言進行Web開發(fā)時,都會遇到讀取 request.Body內(nèi)容的問題,這篇文章主要給大家介紹了關(guān)于go讀取request.Body內(nèi)容踩坑實戰(zhàn)記錄的相關(guān)資料,需要的朋友可以參考下2023-11-11使用Go語言玩轉(zhuǎn) RESTful API 服務(wù)
RESTful API是一種基于HTTP協(xié)議的API設(shè)計風格,遵循REST架構(gòu)風格,這篇文章主要為大家介紹了如何通過Go語言構(gòu)建RESTful API服務(wù),有需要的可以了解下2025-02-02