Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > GO语言支付宝沙箱对接

GO语言支付宝沙箱对接的实现

作者:她似晚风般温柔789

本文介绍了如何使用GO语言对接支付宝沙箱环境,包括秘钥生成、SDK安装和代码实现等步骤,详细内容涵盖了从秘钥生成到前端代码的每个阶段,为开发者提供了一条清晰的指引

1.1 官网

沙箱官网:

https://open.alipay.com/develop/sandbox/app

秘钥用具下载:

https://opendocs.alipay.com/common/02kipk?pathHash=0d20b438

image-20231027214014588

1.2 秘钥生成(系统默认)

image-20231027214829962

1.3 秘钥生成(软件生成)

image-20231027214209352

image-20231027214306694

image-20231027214456066

****

image-20231027214551413

image-20231027214642751

1.4 golan 安装 SDK

go get -u github.com/smartwalle/alipay/v3

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.5 GoLand 代码

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" //支付宝回调
	p.ReturnURL = "http://192.168.137.188:5173/#/pages/pay-success/pay-success" //支付后调转页面
	p.Subject = "云尚校园-订单支付"                                                     //标题
	p.OutTradeNo = orderID                                                      //传递一个唯一单号
	p.TotalAmount = totalPrice                                                  //金额
	//p.ProductCode = "QUICK_WAP_WAY"
	p.ProductCode = "FAST_INSTANT_TRADE_PAY" //网页支付
	var url2 *url.URL
	url2, err = client.TradePagePay(p)
	if err != nil {
		fmt.Println(err)
	}

	var payURL = url2.String()
	println(payURL)
	return payURL
}

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"`
}
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"`        // 订单状态
	OrderTips       string `gorm:"type:varchar(200); not null"`        // 订单备注
	OrderTotalPrice string `gorm:"type:varchar(100); not null"`
	ShopID          string `gorm:"type:varchar(100); not null"`
}
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
}

server:
  port: 9999

datasource:
  diverName: mysql
  host: 127.0.0.1
  port: 3306
  database: go-app
  username: root
  password: 123456
  charset: utf8
package controller

import "github.com/gin-gonic/gin"

type PayController interface {
	AddShopPay(ctx *gin.Context)
	OrderPay(ctx *gin.Context)
}
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")
}
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
}

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))

	// 定义路由和处理函数
	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>
		<!-- 自定义导航栏 -->
		<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="关闭" 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>

到此这篇关于GO语言支付宝沙箱对接的实现的文章就介绍到这了,更多相关GO语言支付宝沙箱对接内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:
阅读全文