2018-11-02 09:24:14 luoyikun 阅读数 496

AndroidStudio:

导入unity与微信的两个jar包

在这里插入图片描述

MyWxShare类

package com.luoyikun.mywxshare;

import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;

import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXTextObject;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.unity3d.player.UnityPlayer;

public class MyWxShare extends Fragment {

    String m_gameObjectName;
    String m_funcName;

    private Context unityContext;
    private Activity unityActivity;

    private static final String TAG = "MyWxShare";


    public static final String APP_ID ="你的appid";
    public IWXAPI api;

    public void regToWx()
    {
        api = WXAPIFactory.createWXAPI(unityContext,APP_ID,true);
        api.registerApp(APP_ID);

    }
    public void UnityFunc(String gameObjectName, String funcName)
    {
        m_gameObjectName = gameObjectName;
        m_funcName = funcName;
    }

    private static MyWxShare Instance = null;

    public static MyWxShare GetInstanceByAndroid(Activity activity,Context context)
    {
        if (Instance == null)
        {
            Instance = new MyWxShare();
            Instance.unityActivity = activity;
            Instance.unityContext = context;

            activity.getFragmentManager().beginTransaction().add(Instance, TAG).commit();
        }
        return Instance;
    }

    public static MyWxShare GetInstance()
    {
        if(Instance == null)
        {
            Instance = new MyWxShare();
            Instance.unityActivity = UnityPlayer.currentActivity;
            Instance.unityContext = Instance.unityActivity.getBaseContext();
            UnityPlayer.currentActivity.getFragmentManager().beginTransaction().add(Instance, TAG).commit();
        }
        return Instance;
    }

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);  // 这一句很重要,保存对该Fragment的引用,防止在旋转屏幕等操作时时丢失引用(Fragment隶属于Activity)
        regToWx();
    }

    // 调用 Unity
    // gameObjectName 为接受消息的Unity 中 GameObject 的名字
    // functionName   为接受消息的GameObject 挂载 C# 脚本中的函数名
    // _content       为发送给Unity 的内容
    public void CallUnity( String _content)
    {
        UnityPlayer.UnitySendMessage(m_gameObjectName, m_funcName, _content);
    }

    private String buildTransaction(final String type) {
        return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
    }

    public void shareText(String text,int wxShareType)
    {
        WXTextObject textObj = new WXTextObject();
        textObj.text = text;
         WXMediaMessage msg = new WXMediaMessage();
         msg.mediaObject =textObj;
         msg.description = text;

         SendMessageToWX.Req req = new SendMessageToWX.Req();
         req.transaction = buildTransaction("text");
         req.message = msg;
         req.scene = wxShareType;
         api.sendReq(req);
    }

    public void shareWebpage(String shareUrl, String title,  String desc,String image,int shareType) {

        WXWebpageObject webPage = new WXWebpageObject();
        webPage.webpageUrl = shareUrl;
        WXMediaMessage msg = new WXMediaMessage(webPage);
        msg.title = title;
        msg.description = desc;
        //图片加载是使用的ImageLoader.loadImageSync() 同步方法
        //并且还要创建图片的缩略图,因为微信限制了图片的大小
       /* Bitmap thumbBmp = Bitmap.createScaledBitmap(ImageLoaderUtil.getBitmap(image), 200, 200, true);
        msg.setThumbImage(thumbBmp);
        thumbBmp.recycle();*/
        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = buildTransaction("webpage");
        req.message = msg;
        //好友
        req.scene =  shareType;
        // 调用api接口发送数据到微信
        api.sendReq(req);
    }
}

WXEntryActivity类:微信返回通知的活动

package 你的app包名.wxapi;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

import com.luoyikun.mywxshare.MyWxShare;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.unity3d.player.UnityPlayer;

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
    private IWXAPI api;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        api = WXAPIFactory.createWXAPI(this, MyWxShare.APP_ID);
        //把接受到的Intent给wxapi这个对象,它会解析回调结果,通过我们实现的IWXAPIEventHandler接口回调给我们
        api.handleIntent(getIntent(), this);
    }

    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        api.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq req) {
    }

    //这里是核心:也就是微信支付结果会通知这个回调函数 在回调里我们通过UnityPlayer.UnitySendMessage通知Unity客户端支付结果
    @Override
    public void onResp(BaseResp resp) {
        //resp就是回调所带的参数 微信->安卓层->Unity  (resp)
        switch (resp.errCode) {
            case BaseResp.ErrCode.ERR_OK:
                //分享成功
                Toast.makeText(this, "分享成功", Toast.LENGTH_SHORT).show();
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                //分享取消
                Toast.makeText(this, "分享取消", Toast.LENGTH_SHORT).show();
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                //分享拒绝
                Toast.makeText(this, "分享拒绝", Toast.LENGTH_SHORT).show();
                break;
        }

        //Toast.makeText(this, retCode, Toast.LENGTH_SHORT).show();
        //通过这个方法 通知Unity层的某个物体上的某个方法  retCode就是调用Unity方法时候传递的参数
        //UnityPlayer.UnitySendMessage("Cube","GetWxRsp", retCode);
        finish();

    }

}

AndroidManifest文件修改

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.luoyikun.mywxshare" >
    <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">

        //回调创建的Activity 如果还有其它 就在下面加入
        <activity android:name="你的包名.wxapi.WXEntryActivity"
            android:exported="true"
            android:launchMode="singleTop"/>
    </application>

</manifest>

Grade修改

apply plugin: 'com.android.library'

android {
    compileSdkVersion 28



    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

}

dependencies {
    implementation files('libs/libammsdk.jar')
    //implementation 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
    implementation files('libs/classes.jar')
}

Unity端:

包签名

在这里插入图片描述
然后用打出的apk用官方签名apk得到签名在后台生成 AppId

C#调用

    public static void WxShareText(string text,EnWxShareType type)
    {
        AndroidJavaObject pluginObject = new AndroidJavaClass("com.luoyikun.mywxshare.MyWxShare").CallStatic<AndroidJavaObject>("GetInstance");
        pluginObject.Call("shareText", text,(int)type);
    }

    public static void WxShareWebpage(string url,string title,string descr,string img, EnWxShareType type = EnWxShareType.WXSceneSession)
    {
        AndroidJavaObject pluginObject = new AndroidJavaClass("com.luoyikun.mywxshare.MyWxShare").CallStatic<AndroidJavaObject>("GetInstance");
        pluginObject.Call("shareWebpage", url,title,descr,img, (int)type);
    }

特别注意

1.得到的签名在微信后台一定要填对,不然返回-6
2.如果测试微信调不起来,清除微信缓存,即可,因为上次的错误信息保存了

2018-11-10 17:43:25 a6214016 阅读数 1499

本文使用的是调起app支付,而且使用的请求参数及其格式校正,已经在后端完成

本文使用的是调起app支付,而且使用的请求参数及其格式校正,已经在后端完成

本文使用的是调起app支付,而且使用的请求参数及其格式校正,已经在后端完成

sdk版本为v15.5.5,androidStudio版本为2.3.2 后续简称as

去官网上下载带有demo的sdk:https://docs.open.alipay.com/54/104509/

Android:

本文借鉴:https://www.jianshu.com/p/86b275da600e

使用as打开这个文件夹

打开完毕后as出现错误,自行百度解决

 

之后切换到android视图打开这个脚本并且删掉继承类

 

接着注释掉onCreate函数,并将h5Pay函数里的startActivity(intent);注释掉

并在脚本里添加以下脚本

private Activity _unityActivity;

	Activity getActivity(){
		if(null == _unityActivity) {
			try {
				Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");
				Activity activity = (Activity) classtype.getDeclaredField("currentActivity").get(classtype);
				_unityActivity = activity;
			} catch (ClassNotFoundException e) {

			} catch (IllegalAccessException e) {

			} catch (NoSuchFieldException e) {

			}
		}
		return _unityActivity;
	}

之后脚本此类出现的error里类似

PayDemoActivity.this

this

换成getActivity(),顺利的话此类中是没有error了,如果有就百度吧
 

 

然后修改payV2函数

我们的支付回调是信任后端的,如果你想本地传入你可以新增此函数并在  break前调用他

boolean callUnity(String gameObjectName, String functionName, String args){
		try {
			Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");
			Method method =classtype.getMethod("UnitySendMessage", String.class,String.class,String.class);
			method.invoke(classtype,gameObjectName,functionName,args);
			return true;
		} catch (ClassNotFoundException e) {

		} catch (NoSuchMethodException e) {

		} catch (IllegalAccessException e) {

		} catch (InvocationTargetException e) {

		}
		return false;
	}

 

 

之后打开它,并修改成如图

 

 

之后打开AndroidManifest.xml,并将红框中的删除

 

如果你此时的项目中已经有了xml,需要注意这个

android:minSdkVersion="**"
android:targetSdkVersion="**"

最好保持一致,否则基本在调起支付Activity后你app就闪退了 

 

之后点击rebuild或者buildAPK

等待build完成后,将此aar包导入到unity Plugins/Android/libs文件下

 

 

之后在unity中去调用

 private AndroidJavaObject currentActivity_Ali_ = null;
    private AndroidJavaObject currentActivity_Ali
    {
        get
        {
            if (currentActivity_Ali_ == null)
            {
                currentActivity_Ali_ = new AndroidJavaObject("com.alipay.sdk.demo.PayDemoActivity");
            }
            return currentActivity_Ali_;
        }
    }
    void CallPaty(string param)
    {
        currentActivity_Ali.Call("payV2", param);
    }

 

至此就可以进行打开app并进行支付。

 

 

 




 


IOS:https://blog.csdn.net/lxj7533621/article/details/51952688?locationNum=2&fps=1

对ios不熟悉,大部分都是抄的这位大佬,只是版本稍微不同,修改了一些地方

 

打开sdk压缩文件夹,并将下面几个文件放入unity内

编写oc,新建一个pay_oc.m,并写入以下内容

#import <Foundation/Foundation.h>
#import "APOrderInfo.h"
#import "APRSASigner.h"
#import <AlipaySDK/AlipaySDK.h>

@implementation APViewController


@end

#if defined (__cplusplus)
extern "C"
{
#endif
#pragma mark   ==============点击订单模拟支付行为==============
    void iospay(const char *orderString )
    {
        //应用注册scheme,在Info.plist定义URL types
        NSString *appScheme = @"ali";
        NSString *orderStr = [NSString stringWithUTF8String:orderString];
        if (orderString != nil) {
            
            [[AlipaySDK defaultService] payOrder:orderStr fromScheme:appScheme callback:^(NSDictionary *resultDic) {
                NSLog(@"reslut = %@",resultDic);
            }];
        }
    }
    
#if defined (__cplusplus)
}
#endif

并这个脚本也放在ios文件夹内并设置如下并点击apply

编写c#侧

 [DllImport("__Internal")]
    private static extern void iospay(string str);
    void TmpPay(string param)
    {
        iospay(param);
    }

之后打包出来在xocode进行后续编译操作,这里使用的是xcode9,大概

xcode的一些基本设置就不讲了

将Enable Bitcode设置为no project和target都要设置

接着添加库,需要参考官方:https://docs.open.alipay.com/204/105295/

 

 

接着添加头文件路径,project和target都要添加,用""引起来,注意中英,他不会提示你,但是会编译不过,就像这样我找了要半个小时

 

之后需要在info.plst添加urlType,自行去上面链接去官方查看,比我说的详细

之后就可以打包出来就可以使用了。

 

 


2017-10-20 16:47:14 z502768095 阅读数 4367

本文章主要将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版本:
这里写图片描述

至于官方说的什么签名啊验证啊订单信息啊以及签名密钥啊这些需要在服务端生成了就请自行完成了。
2017-03-18 15:07:42 ZhangDi2017 阅读数 16339

这篇文章前面讲的创建Android Studio工程的流程是不正确的!!!


最近帮一个群里的朋友接了一下支付宝的SDK,开发环境是Unity 5.4.x + 最新的Android Studio2.3版本,最终Android Studio输出的文件格式是aar而不是之前的jar,鉴于网上的文章大多数是基于Eclipse + jar包,所以记录一下基于Android Studio进行开发的过程,供大家参考。

下载与整理支付宝SDK

首先下载最新的支付宝SDK,解压缩后找到alipay_demo和alipay_sdk文件夹,它们分别是Eclipse demo工程和是支付宝的jar包。接下来的步骤的会用到这两个文件夹里的内容。

创建并配置Android Studio工程

创建一个新的Android工程,Package Name要和Unity -> PlayerSettings里的Bundle Identifier保持一致,Minimum API Level最好也保持一致,防止出现意外的问题(没测过)。
设置Application Name和Company Name。当然Package Name在创建工程后也能修改,不过很麻烦就是了(代码里的可以批量修改,但是AndroidManifest里的需要手动修改)。
设置Minimum API Level,API Level越低所能支持的设备越多,但为了向下兼容低版本的SDK,高版本的一些特有功能将无法使用。这里我选择了API Level 9,即Android 2.3.1,这样发布出来的插件可以跑在100%的安卓手机上了。
Unity中Identification设置示例如下(Unity里的必须是小写!因为Android Studio导出的PackageName是小写):

接着选择Activity的模版,我们选择Empty Activity。因为不需要编写Android原生界面。

然后是设置Activity的名字界面,因为我们不需要编程Android界面,所以取消勾选Generate Layout File选项。不取消也可以,可以创建工程后手动删除Layout文件夹。


至此,完成创建,工程结构应该如图所示:

这里面有许多不需要的东西,比如测试工程,图标资源文件和安卓原生主题的配置文件。我们将其全部删除,删除完毕后工程清单如下所示:

可以看到,我们只保留了两个文件—— AndroidManifest.xml和MainActivity。打开自动生成的AndroidManifest.xml,可以发现有许多关于应用的配置:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.soulgame.magicgame">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>
这里的android:icon,android:label,android:roundIcon和android:theme是不需要的,删除它们。同时必须在<activity>标签里插入一行<meta-data>属性,应该是Unity打包时Merge AndroidManifest时需要的,修改后如下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.soulgame.magicgame">

    <application
        android:allowBackup="true"
        android:supportsRtl="true">
        <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>
最后,因为我们输出的是一个库而不是一个apk,所以需要修改输出的结果,打开Gradle Scripts(Gradle是一种安卓构建脚本)下的build.gradle(Moudle:app),将第一行的:
apply plugin: 'com.android.application'
修改为:
apply plugin: 'com.android.library'
点击上方的sync now,会出现错误提示:
Error:Library projects cannot set applicationId. applicationId is set to 'com.soulgame.magicgame' in default config.
这是因为库文件不能设置applcation Id,另外build.gradle会包含单元测试的配置,也需要删除,如下图所示:

重新点击sync now,提示错误已经消失了。注意这个过程可能会发生其他的问题,如提示build-tools或platform版本过低的提示等等,这时候按照提示给出的方案更新SDK即可。
至此,基本环境配置完毕,接下来就是接入支付宝SDK了。

接入支付宝SDK

首先我们需要引入支付宝SDK的jar包,将alipay_sdk下的alipaySdk-20XXXXXX.jar和Unity提供的jar包拷贝到项目路径/app/libs文件夹下,Unity提供的jar包路径是:
Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar
如果你的项目采用il2cpp编译,那么路径则是:
Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Classes\classes.jar

然后回到AndroidStudio,菜单栏选择File -> Project Structure界面,点击app -> Dependencies如下图所示:

点击旁边的减号,删掉目前这三个以来库,然后点击加号 -> Jar Dependency,选择刚才拷贝到Libs下面的那两个jar文件,点击确定。可以发现build.gradle(Moudle:app)下depedencies里出现了支付宝的Sdk jar包,完整的build.gradle如下:
apply plugin: 'com.android.library'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile files('libs/alipaySdk-20170309.jar')
    compile files('libs/classes.jar')
}

到这里后,我们先来测试一下配置是否正确,再进行下面的步骤。
点击Android Studio左下角的Build Variants,如图:


将debug修改为release:

最后点击菜单栏Build -> Build APK,稍等,如果出现Build Successfully的提示,说明一切正常:

那么,生成的什么呢?点击Show in Explorer,选择outputs -> aar,会发现一个app-release.aar。这就是build生成的文件,aar可以视为jar的升级版,相关区别大家可以自行搜索。其实它们都只是一个zip文件。
注意:
生成的aar文件里,我们需要删除libs/class.jar!将aar文件后缀改为zip,使用压缩软件删除即可。因为Unity在打包时,会将自带的那个classes.jar拷贝进apk,如果aar里的classes.jar不删除,打包时就会产出冲突,得到下面的错误:
IOException: Failed to Move File / Directory from 'Temp/StagingArea\android-libraries\app-release\classes.jar' to 'Temp/StagingArea\android-libraries\app-release\libs\classes.jar'.
也就是说,每次我们测试后,都需要将aar里的这个jar包手动删除。

接下来就是正式开始参考支付宝提供的Demo和官方文档写支付方法了,包括添加混肴规则,修改AndroidManifest.xml增加Activity以及相关的权限设置等等。
其中添加混肴规则需要在Gradle Scripts/proguard-rules.pro里添加对应的规则:
-libraryjars libs/alipaySDK-20XXXXXX.jar //这里改成你所使用的SDK jar版本
 
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}

研究支付宝给出的Demo可以发现,支付宝支付函数只需要一个加密后的订单信息字符串:
public void Pay(final String orderInfo)
{
    Runnable payRunnable = new Runnable()
    {

        @Override
        public void run()
        {
            PayTask alipay = new PayTask(MainActivity.this);
            Map<String, String> result = alipay.payV2(orderInfo, true);
            Message msg = new Message();
            msg.what = SDK_PAY_FLAG;
            msg.obj = result;
            mHandler.sendMessage(msg);
        }
    };

    Thread payThread = new Thread(payRunnable);
    payThread.start();
}
orderInfo可以在客户端生成,需要AppId,pid以及RSA等等,这样做不安全,推荐的做法是由服务端生成订单信息并加密(生成相关的逻辑在Demo里已经给出了),然后传递给客户端,客户端支付完成后,支付宝将执行一个配置好的URL,例如通知服务端支付完毕,而客户端在支付完成后提示支付成功与否的信息只能作为参考。
最后,附上一份由服务端传入订单信息的代码:
package com.soulgame.magicgame;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.widget.Toast;

import com.alipay.sdk.app.PayTask;
import com.unity3d.player.*;

import java.util.Map;

public class MainActivity extends UnityPlayerActivity
{
    private static final int SDK_PAY_FLAG = 1;
    private static final String RESULT_SUCCESS = "9000";
    private static final String TIP_PAY_SUCCESS = "支付成功";
    private static final String TIP_PAY_FAILED = "支付失败";

    // 支付结果回调,仅作参考,以服务端确认为准!
    @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();
                    if (TextUtils.equals(resultStatus, RESULT_SUCCESS))
                    {
                        Toast.makeText(MainActivity.this, TIP_PAY_SUCCESS, Toast.LENGTH_SHORT).show();
                    } else
                    {
                        Toast.makeText(MainActivity.this, TIP_PAY_FAILED, Toast.LENGTH_SHORT).show();
                    }
                    break;
                }
                default:
                    break;
            }
        }

        ;
    };

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    }
    // Unity中调用
    public void Pay(final String orderInfo)
    {
        Runnable payRunnable = new Runnable()
        {

            @Override
            public void run()
            {
                PayTask alipay = new PayTask(MainActivity.this);
                Map<String, String> result = alipay.payV2(orderInfo, true);
                Message msg = new Message();
                msg.what = SDK_PAY_FLAG;
                msg.obj = result;
                mHandler.sendMessage(msg);
            }
        };

        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }
}

在Unity中进行调用

在Assets下创建Plugins文件夹,然后在Plugins下创建Android文件夹,将aar和AndroidManifest.xml文件复制到该文件夹下。使用起来可以参考Unity官方文档
下面演示了客户端生成字符串的C#脚本,注意商品描述不能有空格!
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;

[System.Serializable]
public class PayInfo
{
    public string subject;  // 显示在按钮上的内容,跟支付无关系
    public float money;     // 商品价钱
    public string title;    // 商品描述
}

public class AlipayUI : MonoBehaviour
{
    public List<Button> buttons = null;
    public List<PayInfo> payInfos = null;
    private AndroidJavaObject currentActivity = null;

    void Start()
    {
        // Init UI
        for (int i = 0; i < buttons.Count; i++)
        {
            var payInfo = payInfos[i];
            buttons[i].GetComponentInChildren<Text>().text = payInfos[i].subject;
#if UNITY_ANDROID && !UNITY_EDITOR
            buttons[i].onClick.AddListener(() => 
            {
                Alipay(payInfo);
            });
#endif
        }
#if UNITY_ANDROID && !UNITY_EDITOR
        // 固定写法
        AndroidJavaClass javaClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        currentActivity = javaClass.GetStatic<AndroidJavaObject>("currentActivity");
#endif
    }

    public void Alipay(PayInfo payInfo)
    {
        // AlipayClient是Android里的方法名字,写死.
        // payInfo.money是要付的钱,只能精确分.
        // payInfo.title是商品描述信息,注意不能有空格.
        currentActivity.Call("AlipayClient", payInfo.money, payInfo.title, "");
    }
}
运行结果:


总结

1.前一部分配置AndroidStudio适用于所有的SDK。
2.支付宝Demo里有授权信息的方法,手机app内支付用不到,删除即可。


2018-07-14 14:32:41 qq_35445058 阅读数 3075

Unity群里一个大佬的技术分享,我也转载过来方便日后查阅,有需要转载的,请注明出处QQ280442832

操作步骤性这东西,时间长了就难免忘记,以防日后要接的时候再次爬坑


目标:导出支付宝插件包(arr包)给UNITY调用

主要三大坑:
                   A坑 Android Studio的安装和配置 提示少这少那,但又下载不了
                   B坑  导出Jar包时总是下载不了需要的文件
                  C坑  写完了代码 没有企业资质如何测试




A坑爬坑方法
     
电脑右下角打开它,左上角设置->高级 

Android Studio 简称AS
AS设置左上角File->Setting

填入代理给你的HTTP代理地址,OK保存

下载支付宝SDK安卓开发包
https://gw.alipayobjects.com/os/rmsportal/mXaaROddYFUrkSJIouil.zip

用AS   打开alipay_demo
B坑解决方法设置如图


这里就是填入LT代理的地址

到这里安装环境已经配置完毕

进入SDK开发环节
这个自带的demo是发布APP的,要把它转换成library
具体参照其他网址


进入开发环节

新建一个unityPay的类

DEMO中 PayDemoActivity 的 public void payV2(View v) {.......}可以看到有一句PayTask(PayDemoActivity.this);
PayTask 需要一个Activity,这里我们传入unityActivity即可

问题unityActivity从哪来得到呢?????????????????
这个问题我查了网上几篇文章
网上大多数的文章是让你让你把unity的类库拖进项目,然后继承unityPlayerAcivity
然后通过unityPlayerActivity的子类来调用方法

UNITY调用

这就是网上大多数的DEMO接入SDK思路

但问题和安卓通信的unityActivity只能有一个,而且我想尽量分离插件的耦合,A接好了我就永远不想动了,以后再拓展B,C,D,E,F
如果他们都继承了unityPlayerActivity 那么谁才是当前活动的unityPlayerActivity?由于不是主要做安卓开发,我就不纠结了

直接不继承unityPlayerActivity

回到 问题unityActivity从哪来得到呢?
我的思路是 C#传到安卓即可


PayTask(PayDemoActivity.this)改成 PayTask(p_act)

具体安卓代码我待会打包上传

代码写完了,要配置支付宝参数

注意RSA2_PRIVATE是私匙,是私匙,是私匙

钥匙生成工具在官网可以下载:解压 secret_key_tools_RSA256_win
生成完毕,打开私钥匙pkcs8.pem文件,复制-----BEGIN PRIVATE KEY-----   中间的内容   -----END PRIVATE KEY-----

赋值到RSA2_PRIVATE
配置XML文件如下

好了如果你是有签约的支付宝ID你可以越过下面的步骤了,这里已经开始正常支付调用了
我是个开发者还没签约ID怎么测试?

你的C坑道路爬坑之路即将开启
支付宝沙箱模式
https://auth.alipay.com/login/ant_sso_index.htm?goto=https%3A%2F%2Fopenhome.alipay.com%2Fplatform%2FmanageHome.htm
申请注册完毕,配置生成好公,私匙,具体参照网上文章
简单步骤就是下载支付宝APP沙箱版,
在AS找个合适的初始化方法写入
EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);切换到沙箱模式
如果你是CTRL+C,CTRL+V发现找不到该类,自己手动打这行代码吧,
我是官网CTRL+C复制这段代码,IDE老提示找不到方法,折腾了大半天


发布模块

由于AS版本不断在变,这个生成路径不好确定,直接搜索

app_debug.arr就是插件包了

拖进UNITY得对应目录



UNITYC#代码调用支付


对比下安卓的方法
拼写正常,发布测试


unity与Android设备Sdk的接入

博文 来自: qq_39646949

支付宝SDK

阅读数 307

没有更多推荐了,返回首页