Unity 、Eclipse Android平台、接入支付宝SDK
本文章主要将Unity 、Eclipse Android平台、接入支付宝SDK支付功能的步骤以及注意事项
1、 unity项目准备
项目名字:XXXXXX
项目包名:com.visizen.alipay
2、 支付宝开发账户准备
准备一个支付宝公司帐号,目前个人是不能使用支付宝支付功能的。公司的支付宝帐号必须在支付宝的蚂蚁金服开放中心通过信息审核。具体审核所需信息和材料请根据网站来完成,审核通过之后在主账号的账户中心扩展自己所需要的合作伙伴角色,等待审核完成之后即可使用相应的开放功能。
3、 进入开发者中心,选择支付接入(这里以App内接入支付为例)
4、 根据自己的需要选择使用场景并填写应用的名字
5、 进入创建的应用概览信息页面,根据项目的内容设置Icon以及功能选项,功能部分内容根据应用的需要进行签约,签约之后功能才能使用。
6、 签约
点击立即签约之后根据系统提示进入签约页面。填写完毕之后点击下一步等待蚂蚁金服审核。审核之后之前选择的功能才可使用。
7、 概览界面的开发设置
注意:接口加签方式(标号3)是必须填写的,1,2,4是可填可不填,根据应用的需要来决定。
8、 接口加签方式(配置**)
配置**是支付这一环节很重要的因素,也是分了两个步骤,生成**和配置**,工具下载地址: https://docs.open.alipay.com/291/106097
8、1生成**
找到下载好的签名工具,双击“RSA签名验签工具.bat”,如图
8、2配置签名
在2中填写应用公钥2048中的内容,保存提交即可,至此开放中心配置完成。
这个时候你需要记录应用的APPID 和RSA签名工具生成的**2048.
9、 下载SDK&demo
下载地址:https://docs.open.alipay.com/54/104509
10、 新建一个Eclipse Android项目
注意: Package Name必须和unity中包名一致!!!Application Name随意。并且生成MainActivity。
11、 Libs包的导入
找到自己的unity安装目录,并且找到[安装目录]Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes下的classes.jar 文件以及之前下载的SDK目录中的alipaySdk-20170922.jar文件以及gson.jar文件(gson.jar文件自行下载亦可使用我的工程里面的gson)
12、 将刚刚拖入到libs的三个jar包加入build path
13、 复制代码并修改错误
将demo中src下的代码全部复制到刚刚新建的Eclipse工程目录的src下面,注意文件包名。之后修改代码因包名导致的错误。将PayDemoActivity.java中的代码全部复制到MainActivity.java中,删除PayDemoActivity.java和ExternalFragment.java。并且新建一个java类名字为OrderBodyInfo,内容写先空着。
14、 修改AndroidManifest.xml
将新建的项目点 AndroidManifest.xml内容修改为如:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.visizen.alipay"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="4"
android:targetSdkVersion="18"
tools:ignore="OldTargetApi" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:label="@string/app_name"
android:theme="@android:style/Theme.Light.NoTitleBar" >
<activity
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
</application>
</manifest>
15、 修改proguard-project.txt
将demo中proguard-project.txt的内容复制到新项目的proguard-project.txt中,并且修改2处的alipaysdk的名字和1处的相同
16、 修改MainActivity.java
1、修改import区域和继承类
package com.visizen.alipay;
import android.annotation.SuppressLint;
//import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
//import android.support.v4.app.FragmentActivity;
import android.text.TextUtils;
import android.util.Log;
//import android.view.View;
import android.widget.Toast;
import java.util.Map;
import com.alipay.sdk.app.PayTask;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
public class MainActivity extends UnityPlayerActivity {
2、填写APPID 和**2048,新建一个String productid。APPID请在开发中心查看,**2048使用之前RSA工具生成的。
17、 完成16步之后删除剩下的所有代码,然后编写如下代码
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@SuppressWarnings("unused")
public void handleMessage(Message msg) {
switch (msg.what) {
case SDK_PAY_FLAG: {
@SuppressWarnings("unchecked")
PayResult payResult = new PayResult((Map<String, String>) msg.obj);
/**
对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。
*/
String resultInfo = payResult.getResult();// 同步返回需要验证的信息
String resultStatus = payResult.getResultStatus();
// 判断resultStatus 为9000则代表支付成功
if (TextUtils.equals(resultStatus, "9000"))
{
// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
Toast.makeText(MainActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
//处理支付结果
PayResultToUnity( productid);
}
else
{
// 该笔订单真实的支付结果,需要依赖服务端的异步通知。
Toast.makeText(MainActivity.this, "支付失败", Toast.LENGTH_SHORT).show();
// PayResultToUnity( productid);
}
break;
}
default:
break;
}
};
};
/**
* 支付宝支付业务
*
* @param v
*/
public String Alipay(String name,String price,String productid)
{
this.productid=productid;
boolean rsa2 = (RSA2_PRIVATE.length() > 0);
Map<String, String> params = OrderInfoUtil2_0.buildOrderParamMap(APPID,name,price,productid, rsa2);
String orderParam = OrderInfoUtil2_0.buildOrderParam(params);
String privateKey = rsa2 ? RSA2_PRIVATE : RSA_PRIVATE;
String sign = OrderInfoUtil2_0.getSign(params, privateKey, rsa2);
final String orderInfo = orderParam + "&" + sign;
Runnable payRunnable = new Runnable()
{
@Override
public void run()
{
PayTask alipay = new PayTask(MainActivity.this);
Map<String, String> result = alipay.payV2(orderInfo, true);
Log.i("msp", result.toString());
Log.i("orderInfo===", orderInfo);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
Thread payThread = new Thread(payRunnable);
payThread.start();
return orderInfo;
}
//返回给Unity
public void PayResultToUnity(String productid)
{
//物体名字, 方法名字 方法的参数
UnityPlayer.UnitySendMessage("MainCamera","PayResult",productid);
}
18、OrderBodyInfo类
研究OrderInfoUtil2_0.java发现订单信息是由json格式组成的,所以用OrderBodyInfo类来动态的修改订单的相关信息。App支付请求参数说明:https://docs.open.alipay.com/204/105465/
OrderBodyInfo类只实现了几个必填参数和一个自定义参数,这些参数的解释见上面的 参数说明。其代码如下:
package com.visizen.alipay;
public class OrderBodyInfo
{
public OrderBodyInfo(String body, String subject, String out_trade_no, String timeout_express, String total_amount,
String product_id) {
super();
this.body = body;
this.subject = subject;
this.out_trade_no = out_trade_no;
this.timeout_express = timeout_express;
this.total_amount = total_amount;
this.product_code="QUICK_MSECURITY_PAY";
this.product_id = product_id;
}
//支付宝业务参数信息
//必填信息
public String body;//对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。如:Iphone6 16G
public String subject;//商品的标题/交易标题/订单标题/订单关键字等。如:大乐透,既是显示在订单信息界面的
public String out_trade_no;//商户网站唯一订单号.如:70501111111S001111119
public String timeout_express;//该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。
//注:若为空,则默认为15d。如:90m
public String total_amount;//订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]
public String product_code;//销售产品码,商家和支付宝签约的产品码,为固定值QUICK_MSECURITY_PAY
//以下信息为可选
public String goods_type;//商品主类型:0—虚拟类商品,1—实物类商品 注:虚拟类商品不支持使用花呗渠道
public String passback_params;//公用回传参数,如果请求时传递了该参数,则返回给商户时会回传该参数。支付宝会在异步通知时将该参数原样返回。本参数必须进行UrlEncode之后才可以发送给支付宝
public String promo_params;//优惠参数 注:仅与支付宝协商后可用. 如: {"storeIdType":"1"}
public String extend_params;//业务扩展参数,详见下面的“业务扩展参数说明” 如: {"sys_service_provider_id":"2088511833207846"}
public String enable_pay_channels;//可用渠道,用户只能在指定渠道范围内支付当有多个渠道时用“,”分隔 注:与disable_pay_channels互斥. 如: pcredit,moneyFund,debitCardExpress
public String disable_pay_channels;//禁用渠道,用户不可用指定渠道支付当有多个渠道时用“,”分隔 注:与enable_pay_channels互斥. 如: pcredit,moneyFund,debitCardExpress
public String store_id;//商户门店编号。该参数用于请求参数中以区分各门店,非必传项 如:NJ_001
//自定义信息
public String product_id;//销售的商品id
}
19、 订单信息处理类OrderInfoUtil2_0.java
找到buildOrderParamMap()方法并且替换为如下代码:
/**
* 构造支付订单参数列表
* @param pid
* @param productname
* @param productprice
* @param productid
* @return
*/
public static Map<String, String> buildOrderParamMap(String app_id, String productname,String productprice,String productid,boolean rsa2) {
Map<String, String> keyValues = new HashMap<String, String>();
keyValues.put("app_id", app_id);
OrderBodyInfo sss=new OrderBodyInfo("xx",productname,getOutTradeNo(),"30m",productprice,productid);
Gson gson=new Gson();
String str = gson.toJson(sss);
keyValues.put("biz_content", str);
keyValues.put("charset", "utf-8");
keyValues.put("method", "alipay.trade.app.pay");
keyValues.put("sign_type", rsa2 ? "RSA2" : "RSA");
keyValues.put("timestamp", "2016-07-29 16:55:53");
keyValues.put("version", "1.0");
return keyValues;
}
并且在头文件中添加:
Import com.google.gson.Gson
之后保存并修改工程中的可能因粗心出现的错误。
20、 导出jar包
21、 jar包导入到unity
找到unity项目中的Plugins目录下的Android文件下的bin文件,没有就新建上面三个文件夹。将20步导出的jar拖到bin文件夹下面。再将之前的alipaysdk和gson这两个包拖到Android目录下的libs目录下。复制Eclipse工程中的整个res文件夹和AndroidManifest.xml到unity的Android文件夹下面。最后的如图:
22、 unity端处理
新建一个场景并保存,名字任意,新建一个C#文件,名字任意,并赋给MainCamera
C#代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[System.Serializable]
public class PayInfo
{
public string subject; // 显示在按钮上的内容,跟支付无关系
public float money; // 商品价钱
public string title; // 商品描述
public string productid; // 商品id
}
public class PayPay : MonoBehaviour
{
public List<Button> buttons = null;
public List<PayInfo> payInfos = null;
private AndroidJavaObject currentActivity = null;
public Text orderinfo;
private string ordersss;
void Start()
{
for (int i = 0; i < buttons.Count; i++)
{
var payInfo = payInfos[i];
buttons[i].GetComponentInChildren<Text>().text = payInfos[i].subject;
buttons[i].onClick.AddListener(() =>
{
Alipaypay(payInfo);
});
}
}
public void Alipaypay(PayInfo payInfo)
{
// AlipayClient是Android里的方法名字,写死.
// payInfo.money是要付的钱,只能精确分.
// payInfo.title是商品描述信息,注意不能有空格.
// 固定写法
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
currentActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");
ordersss = currentActivity.Call<string>("Alipay", payInfo.title, payInfo.money.ToString(), payInfo.productid);
Formatsss(ordersss);
}
private void Formatsss(string ss)
{
orderinfo.text = null;
string[] temp = ss.Split('&');
for (int i = 0; i < temp.Length; i++)
{
orderinfo.text = orderinfo.text + temp[i] + "\n";
}
}
public void PayResult(string productid)
{
buttons[int.Parse(productid)].gameObject.GetComponent<Image>().color = Color.red;
}
}
23、 场景设置与打包
25、 安装测试
付款或者取消之后界面上显示的红字是刚刚的订单信息。请自行分析。不解释了
26、 说明:
1、unity调用jar包中方法:
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
currentActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");
currentActivity.Call<string>("Alipay", payInfo.title, payInfo.money.ToString(), payInfo.productid);
前两行为固定写法,第三行为可变写法,具体的请参照unity官方文档。
2、jar包中调用unity方法:
UnityPlayer.UnitySendMessage("MainCamera","PayResult",productid);
3、unity版本:5.6.0f3
Eclispe版本:
至于官方说的什么签名啊验证啊订单信息啊以及签名**啊这些需要在服务端生成了就请自行完成了。
上一篇: 支付宝pc端支付接入PHP实现