基于uniapp开发抖音小程序
1、签名工具类
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Common.Utils
{
/// <summary>
/// 字节跳动小程序签名
/// </summary>
public class ApiBllPayTiktokAppSignUtil
{
// 支付秘钥值,支付信息配置里的SALT
private const string Salt = "";
public static string GetSign(Dictionary<string, Object> paramsDict)
{
var paramsList = new ArrayList();
foreach (var item in paramsDict)
{
var k = item.Key;
var v = item.Value;
if ("other_settle_params".Equals(k))
{
continue;
}
var value = v.ToString().Trim();
if (value.StartsWith("\"") && value.EndsWith("\"") && value.Length > 1)
{
value = value.Substring(1, value.Length - 1);
}
value = value.Trim();
if ("".Equals(value) || "null".Equals(value))
{
continue;
}
switch (k)
{
case "app_id":
case "thirdparty_id":
case "sign":
break;
default:
paramsList.Add(value);
break;
}
}
paramsList.Add(Salt);
// 按照 ASCII 编码进行排序
var paramsArray = (string[])paramsList.ToArray(typeof(string));
Array.Sort(paramsArray, string.CompareOrdinal);
var signStr = string.Join("&", paramsArray);
return GetMd5(signStr);
}
private static string GetMd5(string sDataIn)
{
var md5 = new MD5CryptoServiceProvider();
byte[] bytValue, bytHash;
bytValue = Encoding.UTF8.GetBytes(sDataIn);
bytHash = md5.ComputeHash(bytValue);
md5.Clear();
var sTemp = bytHash.Aggregate("", (current, t) => current + t.ToString("X").PadLeft(2, '0'));
return sTemp.ToLower();
}
}
}
2、下订单工具类
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace Common.Utils
{
/// <summary>
/// 抖音支付工具
/// </summary>
public class TiktokAppPayUtil
{
//抖音小程序APPID
public static string AppId { get; set; } = "";
/// <summary>
/// 预下单
/// </summary>
public static string CreateOrder(string subject, string body, decimal amount)
{
string url = "https://developer.toutiao.com/api/apps/ecpay/v1/create_order";
CreateOrderRequest requestData = new CreateOrderRequest
{
app_id = AppId,
out_order_no = Guid.NewGuid().ToString(),
total_amount = (int)1,
subject = subject,
body = body,
valid_time = 172800,
};
requestData.sign = TiktokAppSignUtil.GetSign(DictUtil.ModelToMap(requestData));
string postData = JsonConvert.SerializeObject(requestData);
return Post(url, postData);
}
private static string Post(string url, string postData)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "application/json";
request.UserAgent = "Mozilla / 5.0(Windows NT 10.0; Win64; x64; rv: 48.0) Gecko / 20100101 Firefox / 48.0"; //火狐用户代理
request.Method = "POST";
byte[] data = Encoding.UTF8.GetBytes(postData);
request.ContentLength = data.Length;
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(data, 0, data.Length);
reqStream.Close();
}
HttpWebResponse resp = (HttpWebResponse)request.GetResponse();
Stream stream = resp.GetResponseStream();
//获取响应内容
string result = "";
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
result = reader.ReadToEnd();
}
return result;
}
}
}
3、小程序前端先调用预订单生成,生成成功后打开收银台
const requestCodeData = {
strSubject: this.buySubject,
strTotalAmout: this.refillMoney,
DepartmentID: paramshelp.BASE_DepartmentID,
DevPrjID: paramshelp.BASE_DevPrjID,
PrjTypeID: this.prjType,
DevPrjTwoType:1,//项目2级类型 1为会员端 2为企业用户
BusinessTypeID:this.businessTypeID,
UserID: storageUtil.getUserData('UserID'),
OrderID: this.orderID ,//订单表订单号
OrderCode:this.orderCode//订单号
};
console.log('请求数据:'+JSON.stringify(requestCodeData));
//调用统一下单
api.ajax({
url: '/WebApiAccount/GetTikTokPayData',
data: requestCodeData,
method: 'GET',
success: (returnPayData) => {
console.log("支付数据:" + JSON.stringify(returnPayData));
if (returnPayData.boolResult) {
var paymentData = returnPayData.returnData;
let urlPrames='&payContent=支付结果&payAmount='+this.refillMoney+'&payDescription='+this.buySubject+'&payCreateDate='+ dateUtils.getNowTime(2) +'&payOrderCode='+this.orderCode;
uni.requestPayment({
provider: 'toutiao',
orderInfo: paymentData.data,//返回订单数据
service: 5,
success: (res) => {
if (res.code == 0) {
// 支付成功处理逻辑,只有res.code=0时,才表示支付成功
// 但是最终状态要以商户后端结果为准
uni.showToast({
icon: 'none',
title: '支付成功',
complete: function() {
//uni.navigateBack();
uni.navigateTo({
url: '/pages/index/paymentInfo?payState=2'+urlPrames+'&payStatusDes=支付成功'
});
return;
}
});
}
else
{
uni.showToast({
icon: 'none',
title: '支付失败,请和管理员联系'
});
}
},
fail: (res) => {
// uni.showModal({
// content: "支付失败,原因为: " + res.errMsg,
// showCancel: false
// })
uni.showModal({
content: "支付失败,请到订单中心重新支付,原因为: " + e.errMsg,
showCancel: false,
complete:function(){
uni.navigateTo({
url: '/pages/index/paymentInfo?payState=3'+urlPrames+'&payStatusDes=支付失败'
});
return;
}
});
},
complete: () => {
this.loading = false;
}
});
} else {
uni.showToast({
icon: 'none',
title: returnPayData.returnMsg
});
this.loading = false;
}
return;
},
error: function() {
uni.showToast({
icon: 'none',
title: '获取统一下单数据出错,请和管理员联系'
});
}
});