Unity3D接入支付宝支付的流程非常复杂,涉及到很多方面(有任何问题都可以在评论区留言,我尽量尽快回复)所以写篇文章记录一下。支付宝支付和微信支付以及其它支付差不多,但是支付宝有沙箱环境,可以很方便地调试,所以选用支付宝平台作为演示。
此教程使用了三个非常大的编辑器:Unity3D 2021.3.29f1c1、Visual Studio 2022、Android Studio 2022.3,其它版本也可以,不过缺一不可。主要流程大概是:编写Unity3D服务端、编写Android Studio SDK、编写Unity3D客户端。
1.准备工作
打开下面这个链接,可以进入到支付宝沙箱控制台。
支付宝沙箱控制台
在沙箱工具页面可以下载到手机端的沙箱APP,用于测试。一定要下载到你的手机上,不能用原生的支付宝!
在沙箱应用页面,登录后可以看到你的应用的详细信息,一会儿要用到这里的很多信息,我这里会把用的到信息标注出来。
支付宝网关地址,默认是 https://openapi-sandbox.dl.alipaydev.com/gateway.do
APPID
应用私钥
应用公钥
2.编写Unity3D服务端
说是Unity3D服务端,但其实不是用Unity3D写的。编写服务端主要用微软的ASP.NET Core Web API技术进行服务提供,此教程中要确保你的手机和电脑能连接同一个Wifi或是路由器。
我们首先打开Visual Studio 2022,点击创建新项目。
找到ASP.NET Core Web API应用,注意不要找错了,微软的东西有特别多名称极其相似的项目模板。点击下一步。
指定一个项目名称,例如我的是:test_Alipay,点击下一步。
为了演示,我用了如下配置,建议和我的配置是一样的。最好选.NET6.0。点击创建。
打开Program.cs可以看到如下代码。
在左侧的依赖项这里,右键-管理NuGet程序包,切换到浏览标签下。
搜索AlipaySDKNet,可以找到AlipaySDKNet.Core,点击右面的安装。
搜索Newtonsoft,可以找到Microsoft.AspNetCore.Mvc.NewtonsoftJson,指定版本号和你的.Net版本一致,点击右面的安装。
C#安装包是肯定不会失败的。
打开左侧的appsettings.json文件,加入一行
"Urls": "http://0.0.0.0:8880",
代表服务从所有IP(0.0.0.0)的8880端口提供,需要服务时只需请求这个IP+端口。
右键Controller文件夹,-添加-新建项,新建一个AlipayController.cs文件。
在新建的AlipayController.cs文件里插入如下代码:
using Aop.Api.Request;
using Aop.Api.Response;
using Aop.Api;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
//改成你自己的项目名称加上“.Controllers”
namespace test_Alipay.Controllers
{
[ApiController]
[Route("Alipay")]
public class AlipayController : ControllerBase
{
/// <summary>支付宝网关地址</summary>
private const string serverUrl = "支付宝网关地址";
/// <summary>APPID</summary>
private const string appId = "APPID";
/// <summary>应用私钥</summary>
private const string privateKeyPem = @"
应用私钥
应用私钥
";
/// <summary>应用公钥</summary>
private const string alipayPublicKey = @"
应用公钥
应用公钥
";
[HttpPost("GetOrderStr")]
public string GetOrderStr(JObject request)
{
string out_trade_no = request["out_trade_no"]?.ToString() ?? Random.Shared.Next(1, 1000000).ToString();
float total_amount = ((float?)request["total_amount"]) ?? 0.01f;
string subject = request["subject"]?.ToString() ?? "测试商品";
string product_code = request["product_code"]?.ToString() ?? "QUICK_MSECURITY_PAY";
IAopClient client = new DefaultAopClient(
serverUrl
, appId
, privateKeyPem
, "json"
, "1.0"
, "RSA2"
, alipayPublicKey
, "utf-8"
, false);
AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();
alipayRequest.SetNotifyUrl("");
Dictionary<string, object> bizContent = new Dictionary<string, object>();
bizContent.Add("out_trade_no", out_trade_no);
bizContent.Add("total_amount", total_amount);
bizContent.Add("subject", subject);
bizContent.Add("product_code", product_code);
//bizContent.Add("time_expire", "2023-10-14 14:58:00");
//商品明细信息,按需传入
//List<object> goodsDetails = new List<object>();
//Dictionary<string, object> goods1 = new Dictionary<string, object>();
//goods1.Add("goods_id", "goodsNo1");
//goods1.Add("goods_name", "子商品1");
//goods1.Add("quantity", 1);
//goods1.Add("price", 0.01);
//goodsDetails.Add(goods1);
//bizContent.Add("goods_detail", goodsDetails);
//扩展信息,按需传入
//Dictionary<string, object> extendParams = new Dictionary<string, object>();
//extendParams.Add("sys_service_provider_id", "2088501624560335");
//bizContent.Add("extend_params", extendParams);
string Contentjson = JsonConvert.SerializeObject(bizContent);
alipayRequest.BizContent = Contentjson;
AlipayTradeAppPayResponse response = client.SdkExecute(alipayRequest);
Console.WriteLine(response.Body);
JObject jObject = new JObject();
jObject["order"] = response.Body;
return jObject.ToString();
}
}
}
注意,将这个类的所有const类型的字符串都改成你自己的设置,详细信息参见代码里的注释对应《准备工作》中的一些参数
为了测试,可以将Program.cs文件改为以下代码:
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Linq;
using System.Text;
namespace test_Alipay
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
//使Controller能接受JObject对象
builder.Services.AddControllers().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseAuthorization();
app.MapControllers();
Task.Run(() =>
{
Thread.Sleep(200);
HttpClient httpClient = new HttpClient();
JObject requestBody = new JObject();
StringContent content = new StringContent(requestBody.ToString(), Encoding.UTF8, "application/json");
httpClient.PostAsync("http://127.0.0.1:8880/Alipay/GetOrderStr", content);
});
app.Run();
}
}
}
可以试着运行一下程序,没问题的话,就进行下一步了。可以看到获取到了order,也就是订单号,在Unity3D中,使用这个东西就可以向支付宝发出支付请求了。
注意事项:安装AlipaySDKNet.Core NuGet包,如果没有Microsoft.AspNetCore.Mvc.NewtonsoftJson的话也要安装一个。
3. 编写Android Studio SDK
由于作者没开发过Android原生APP,所以对Android Studio不是很熟悉,如有错误,请多包涵,可以去其他博主那里看看他们的文章参考一下。
打开Android Studio 2022.3。
新建项目,选择Empty Views Activity,点击Next。
应用如下配置:这里记住你的Package name,一会儿有用!(而且包名必须和Unity3D中的包名一致,请注意!)
点击Finish后,就可以创建工程了,第一次创建会极其地慢,需要耐心等待,并且可能会出现网络连接问题。
等待右下角进度条消失…
点击顶部菜单栏File-Project Structure,
这里删去原有的模块。
顶部菜单栏,File-New-New Module,
选中Android Library,必须是Library,指定一个Module name(随意,不过最好和我一样),Package name是项目包名.模块名。
切换到Project视图,可以看到目录结构。
这里我们需要三个东西:支付宝官方的SDK(.aar包)、Unity的SDK、Unity的Java类。
以下是支付宝的SDK的下载链接,链接是我自己的链接,所以时间久了可能会失效。不过网上有很多这个资源,支付宝开放平台上也可以下载的到,或者直接从Android Studio里安装包也可以(不过需要导出aar包,因为Unity里要用到)
链接: 支付宝aar包:alipaysdk-android-15.8.16.aar
下载好了后,复制到桌面(一会儿用),并直接复制到项目的Alipay模块的libs文件夹下,注意:路径别错了。
接下来需要准备Unity的JavaSDK和Unity的Java类,这两个东西在Unity编辑器安装的位置下能找得到。
打开Unity Editor安装的位置,不知道的可以去Unity Hub里找位置:
搜索classes.jar,找到后复制到桌面上。一共有4个,找到il2cpp\Release\目录下的。(或Mono的也可以)
再搜索UnityPlayerActivity,找到后复制到桌面上。
classes.jar放到这里,
UnityPlayerActivity.java放到这里,
然后打开build.gradle文件:
在最下面加入一行:点击同步设置
compileOnly fileTree(include: ['*.jar','*.aar'], dir: 'libs')
打开UnityPlayerActivity.java脚本,加入三行引用:
import com.unity3d.player.IUnityPlayerLifecycleEvents;
import com.unity3d.player.MultiWindowSupport;
import com.unity3d.player.UnityPlayer;
接下来新建一个java脚本:AlipayActivity.java
将其改为以下代码:
package com.csdn.test_alipay.Alipay;//换成你自己的包名
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import com.alipay.sdk.app.EnvUtils;
import com.alipay.sdk.app.PayTask;
import com.unity3d.player.UnityPlayer;
public class AlipayActivity extends UnityPlayerActivity {
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
// 支付宝支付
public void AliPay(final String orderInfo, final Context context, String callBackObjectName, String CallBackFuncName)
{
// 沙箱环境时需要这行代码,正式环境下删除掉!!!
EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);
Log.i("Unity", " >>> enter alipay native");
Runnable payRun = new Runnable() {
@Override
public void run() {
PayTask task=new PayTask((Activity)context);
String result= task.pay(orderInfo, true);
Log.i("Unity", "onALIPayFinish, result = " + result);
// 这里可以自己添加Unity回调接收
UnityPlayer.UnitySendMessage(callBackObjectName, CallBackFuncName, result);
}
};
Thread payThread = new Thread(payRun);
payThread.start();
}
}
做完了这些就可以打包了(如果没有编译错误),顶部菜单栏Build-Make Module,
找到这个文件(Build出来的文件):Alipay-debug.aar
右键,在文件夹中打开:
复制到桌面上,有了这两个文件(Alipay-debug.aar、alipaysdk-android-15.8.16.aar)就可以在Unity中很方便地进行调用了。
4.编写Unity3D客户端
做着做着,都忘了自己要做啥了,终于开始咱们的Unity项目,接下来就到了咱们熟悉的领域了。下面的教程就没有那么详细了,不过步骤还是不能少的。
新建Unity项目。(2D核心模板也可以,其实都一样,我的这个2D Mobile模板是有bug的,打包不了)
在Build Settings里切换一下平台。
在Player Settings里改一下包名:一定要和Android Studio里的项目包名一致(我的是com.csdn.test_alipay)。
再将API Level改成7.0(24)
可以先打个包看看有没有问题,没问题就进行接下来的内容:
1.调用Unity服务端的服务获取order字符串
安装Newtonsoft.Json包,
新建脚本文件AlipayManager.cs,并挂载到一个物体上。
这个物体的名称一会儿还会用到,所以这个记住了。
打开脚本,将脚本改成如下:
using System;
using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using Newtonsoft.Json.Linq;
public class AlipayManager : MonoBehaviour
{
[Header("点击支付的按钮")]
public Button payButton;
[Header("用于输出调试信息的文本")]
public Text debugText;
private void Awake()
{
//绑定按钮事件
payButton.onClick.AddListener(OnPayButtonClick);
}
/// <summary>
/// 点击支付的按钮 按下时调用
/// </summary>
private void OnPayButtonClick()
{
StartCoroutine(GetOrderStr(orderStr =>
{
if(string.IsNullOrEmpty(orderStr))
{
return;
}
//原生调用支付宝支付
ShowALiPay(orderStr);
}));
}
/// <summary>
/// 原生调用支付宝支付
/// <param name="orderInfo">临时的订单号</param>
/// </summary>
private void ShowALiPay(string orderInfo)
{
debugText.text += "\n服务器返回订单号 >>>> " + orderInfo.Substring(0, 20);
Debug.Log("服务器返回订单号 >>>> " + orderInfo); // 此处是后端返回的订单信息
#if UNITY_ANDROID
//固定不变
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
//固定不变
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
//这里要改成你自己的 包名.模块名.AlipayActivity !!!!!!
AndroidJavaObject utils = new AndroidJavaObject("com.csdn.test_alipay.Alipay.AlipayActivity");
//这里的第一个参数是Java函数名,第四个参数是当前脚本挂载物体的名称,一定要对!!!!!!
//最后一个参数是回调的Unity3D中的函数名,下面有
utils.Call("AliPay", orderInfo, currentActivity, "AlipayManager", "ALiPayResult");
#endif
}
/// <summary>
/// 支付宝 支付回调
/// </summary>
/// <param name="result">支付结果通知,支持本地通知和云通知(结果传回到你的服务端中),这里为了简单只展示了本地通知</param>
public void ALiPayResult(string result)
{
debugText.text += "\n unity 获取支付宝回调>>>> " + result;
Debug.Log(" unity 获取支付宝回调>>>> " + result);
}
/// <summary>
/// 向当前网络的本机请求订单号
/// </summary>
/// <param name="callback"></param>
/// <returns></returns>
private IEnumerator GetOrderStr(Action<string> callback)
{
//构建请求体
JObject request = new JObject();
request["out_trade_no"] = UnityEngine.Random.Range(1,100000000).ToString();
request["total_amount"] = 0.01f;
request["subject"] = "测试商品";
request["product_code"] = "QUICK_MSECURITY_PAY";
//初始化WebRequest 这里的地址要改成你网络的地址!!!!!!
UnityWebRequest webRequest = UnityWebRequest.Post("http://183.173.67.199:8880/Alipay/GetOrderStr/", string.Empty);
webRequest.SetRequestHeader("Content-Type", "application/json;");
//webRequest.SetRequestHeader("Accept", "application/json");
//设置超时时间(秒)
webRequest.timeout = 10;
//设置发送消息的缓存区
webRequest.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(request.ToString()));
//等待返回消息
yield return webRequest.SendWebRequest();
//成功接收到消息
if (webRequest.result == UnityWebRequest.Result.Success)
{
//解析Json字符串
JObject jObject = JObject.Parse(webRequest.downloadHandler.text);
//获取订单号
string orderStr = jObject["order"].ToString();
//回调
callback.Invoke(orderStr);
}
else
{
debugText.text += "\n错误信息:" + webRequest.error;
Debug.Log("错误信息:" + webRequest.error);
debugText.text += "\n向当前网络的本机请求订单号失败,可能是Unity服务端程序(Web API)没有开始,或是IP和端口号没有设置正确";
Debug.Log("向当前网络的本机请求订单号失败,可能是Unity服务端程序(Web API)没有开始,或是IP和端口号没有设置正确");
//失败回调
callback.Invoke(null);
}
webRequest.Dispose();
yield break;
}
}
这里面有几个参数很重要:
查看注释带有6个感叹号的参数,一定要根据你自己设置的参数进行修改,其中最后一个参数我要说明一下:
UnityWebRequest webRequest = UnityWebRequest.Post(“http://183.173.67.199:8880/Alipay/GetOrderStr/”, string.Empty);
这个参数要查看你的Wifi的IPv4的地址,找到你的Wifi的属性:
最下面的这行IP地址填入到你的代码中:
将"http://183.173.67.199:8880/Alipay/GetOrderStr/"中的183.173.67.199改成你自己的。
2.根据order字符串请求支付
在Unity场景中添加一个用于支付的按钮和调试文本框:
将这两个物体拖到脚本中:
最后有个很重要的事:将刚才生成的两个arr包拖到Unity3D的资源文件夹下,文件夹的路径要和我一样!要不然Unity可能检测不到。
5.运行测试
先启动服务程序(ASP.NET Core Web API),如图所示开启成功。
确保你的手机和你的电脑连接的是同一个Wifi或是路由器,要不然访问不到!
接下来打开Unity Android端的APP,点击支付
如图所示即为支付成功:
可以看到有一行:“msg”:“Success”。文章来源:https://www.toymoban.com/news/detail-861743.html
如果对本教程有任何问题,欢迎在评论区评论,我看到后一定尽快回复。文章来源地址https://www.toymoban.com/news/detail-861743.html
到了这里,关于Unity Android平台接入支付宝支付全流程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!