支付宝移动支付安卓与Javaweb服务端的实现,更安全

1.前言

之前写了一篇安卓支付宝支付的文章,但是那些隐私数据都在安卓端,包括私钥,支付宝企业账号,还有APPID,这样太不安全了,另外,如果不设服务端做异步通知的话,同样也是不安全的,容易被人钻空子。因此,这篇文章是在安卓端在发起支付请求时,先向服务端请求支付接口,然后安卓才能发起支付,支付成功后,安卓会有个同步的通知支付成功,但是对于支付成功的后续订单等操作仍依赖服务端的异步通知,当服务端接收到支付宝发过来的异步通知后,才把订单状态修改为已付款。

2.效果演示

(1)app
在这里插入图片描述

(2)服务端异步通知截图

在这里插入图片描述

3.前期工作

1.注册企业账号;
2.创建应用 ;
3.配置应用 ;
4.开启支付APP支付 ;
5.签约,在支付宝开放平台中跟着步骤走就可以完成的操作,为对接做准备工作。
6.去管理中心得到应用的APPID;
7.用支付宝开放平台开发助手生成一一对密钥,分别是应用公钥和私钥在这里插入图片描述
8.用应用公钥去生成支付宝公钥,如图,点击 设置公钥在这里插入图片描述
9.填写异步通知URL;
然后就可以开始做服务端和客户端的开发啦!

4.服务端的实现

(1)首先要配置的东西:APP_ID、APP_PRIVATE_KEY(用支付宝开放平台开发助手生成的私钥)、ALIPAY_PUBLIC_KEY(支付宝公钥)。

对于怎么才能得到APPID。首先你得是企业账号才能接入支付宝支付,因为还要签约的。

在这里想说明一下,很多人都分不清私钥和公钥到底要怎么用,用哪一个?其实很简单。首先是打开这个支付宝开放平台开发助手,如下图
在这里插入图片描述

在这里插入图片描述
点击生成密钥,就会生成一个公钥和一个私钥。这个私钥就是我上面所说的APP_PRIVATE_KEY,但是这个生成的公钥有什么用呢?
这个公钥要把它放到支付宝开发平台那里,把它生成支付宝公钥,而生成的支付宝公钥,就是我上述所说的ALIPAY_PUBLIC_KEY。至于普通的公钥怎么才能生成支付宝公钥呢?
在这里插入图片描述
点击设置公钥,就能生成支付宝公钥了。
有写可能会问,为什么要这么做呢?我们要知道这三个密钥的作用分别是什么,用着才不会乱。
1.应用私钥:用于请求支付宝数据加签(放在服务端);
2.应用公钥:用于提供给支付宝,让支付宝去拿着公钥获取你私钥加签后的数据;(放在支付宝开发平台用于生成支付宝公钥);
3.支付宝公钥:是用来接收支付宝回调信息的(放在服务端);
这样说应该可以明白了吧。

(2)jar包:支付宝SDK.jar包在这里插入图片描述

(3)代码实现:springboot

在这里插入图片描述
6个java类
在这里插入图片描述

在这里插入图片描述

1.先来看看 DemoApplication.java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

2.BaseEntity.java

public class BaseEntity {
    private String code;
    private String message;
    private Object content;

    public BaseEntity(String code, String message, Object content) {
        this.code = code;
        this.message = message;
        this.content = content;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getContent() {
        return content;
    }

    public void setContent(Object content) {
        this.content = content;
    }
}

3.AlipayConfig.java 这个类是配置三个参数的

public class AlipayConfig {
     public static final String APP_ID = "这里填签约后的APPID";
    public static final String APP_PRIVATE_KEY = "这里填用支付宝开放平台开发助手生成的应用私钥";
    public static final String ALIPAY_PUBLIC_KEY = "这里填支付宝公钥";
    public static final String CHARSET = "UTF-8";
}

4.AlipayController.java 当客户端发起支付宝请求时,会先生成一个商户号,并根据这个商户号来新建订单表,订单状态暂时为未支付。当客户端支付成功之后,服务端会接收到异步通知,当通知支付成功的时候,可以把订单的状态改成已支付。但是要确保异步通知的URL必须是外网可以访问得到。
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.example.demo.bean.BaseEntity;
import com.example.demo.config.AlipayConfig;
import com.example.demo.utils.AliRequestParam;
import com.example.demo.utils.OrderNo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@RestController
public class AlipayController {

    @SuppressWarnings("unchecked")
	@RequestMapping(value = "/alipay", method = RequestMethod.POST)
    public Object alipayment(@RequestParam String payMoney) {

        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json",
                AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,
                "RSA2");
        String out_trade_no=OrderNo.getOutTradeNo();
        System.out.println("商户订单号"+out_trade_no);
        //构建支付宝请求参数
        AlipayTradeAppPayRequest request = AliRequestParam.startRequestAli(payMoney,out_trade_no);
        try {
            //这里和普通的接口调用不同,使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,客户端可以直接发起支付,无需再做处理。
            @SuppressWarnings("rawtypes")
			Map map = new HashMap();
            map.put("orderString", response.getBody());
          
            BaseEntity baseEntity = new BaseEntity("200", "支付宝下单成功", map);
            //这里做生成订单操作,订单状态为未支付
            
            return baseEntity;
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        BaseEntity baseEntity = new BaseEntity("200", "支付宝下单失败", null);

        return baseEntity;


    }
    
    
  //异步通知
    @RequestMapping(value = "/pay_notify",method = RequestMethod.POST)
    public void notifyUrl(HttpServletResponse response,HttpServletRequest request) throws IOException, AlipayApiException {
        System.out.println("异步通知");
        PrintWriter out  = response.getWriter();
        request.setCharacterEncoding("utf-8");//乱码解决,这段代码在出现乱码时使用
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for(String str :requestParams.keySet()){
            String name = str;
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params,  AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2"); //调用SDK验证签名

        if(!signVerified) {
            System.out.println("验签失败");
            out.print("fail");
            return;
        }

        //商户订单号,之前生成的带用户ID的订单号
        String out_trade_no = params.get("out_trade_no");
        //支付宝交易号
        String trade_no = params.get("trade_no");
        //付款金额
        String total_amount = params.get("total_amount");
        //交易状态
        String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
        
//        String appId=params.get("app_id");//支付宝分配给开发者的应用Id
//        String notifyTime=params.get("notify_time");//通知时间:yyyy-MM-dd HH:mm:ss
//        String gmtCreate=params.get("gmt_create");//交易创建时间:yyyy-MM-dd HH:mm:ss
        String gmtPayment=params.get("gmt_payment");//交易付款时间
//        String gmtRefund=params.get("gmt_refund");//交易退款时间
//        String gmtClose=params.get("gmt_close");//交易结束时间
//        String tradeNo=params.get("trade_no");//支付宝的交易号
//        String outTradeNo = params.get("out_trade_no");//获取商户之前传给支付宝的订单号(商户系统的唯一订单号)
//        String outBizNo=params.get("out_biz_no");//商户业务号(商户业务ID,主要是退款通知中返回退款申请的流水号)
//        String buyerLogonId=params.get("buyer_logon_id");//买家支付宝账号
//        String sellerId=params.get("seller_id");//卖家支付宝用户号
//        String sellerEmail=params.get("seller_email");//卖家支付宝账号
//        String totalAmount=params.get("total_amount");//订单金额:本次交易支付的订单金额,单位为人民币(元)
//        String receiptAmount=params.get("receipt_amount");//实收金额:商家在交易中实际收到的款项,单位为元
//        String invoiceAmount=params.get("invoice_amount");//开票金额:用户在交易中支付的可开发票的金额
//        String buyerPayAmount=params.get("buyer_pay_amount");//付款金额:用户在交易中支付的金额  
//        String tradeStatus = params.get("trade_status");// 获取交易状态 

        

        if(trade_status.equals("TRADE_FINISHED")){
            /*此处可自由发挥*/
            //判断该笔订单是否在商户网站中已经做过处理
            //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
            //如果有做过处理,不执行商户的业务程序
            //注意:
            //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
        }else if (trade_status.equals("TRADE_SUCCESS")){
         //这里就可以更新订单状态为已支付啦
         
        	
        }

        out.print("success");
    }
   

}

5.AliRequestParam.java
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;

public class AliRequestParam {

    public static AlipayTradeAppPayRequest startRequestAli(String payMoney,String trade_no) {
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
      
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("某公司");
        model.setSubject("某商品");
        model.setOutTradeNo(trade_no);
        model.setTimeoutExpress("30m");
        model.setTotalAmount(payMoney);
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl("这里填你服务端的地址+异步通知的地址,如:http://example.com/pay_notify");//这里要注意的是,这个地址外网必须要能访问,不然服务端无法接收到异步通知的,你只需要把example.com改成你的ip地址和端口号即可,如果做了端口映射的话就只填ip地址即可
        return request;
    }

}

6.OrderNo.java
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Random;

public class OrderNo {
    /**
     * get the out_trade_no for an order. 生成商户订单号,该值在商户端应保持唯一(可自定义格式规范)
     */
    public static String getOutTradeNo() {
        SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());
        Date date = new Date();
        String key = format.format(date);

        Random r = new Random();
        key = key + r.nextInt();
        key = key.substring(0, 15);
        return key;
    }
}

7.application.properties
server.port=8080

8.pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>demo</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.8.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

服务器到这就完成啦。

5.APP端的实现

在这里插入图片描述

在这里插入图片描述

1.依赖
    //http请求 
    implementation 'com.zhy:okhttputils:2.6.2'
    implementation 'com.squareup.okhttp3:okhttp:3.10.0'
    implementation 'com.alibaba:fastjson:1.2.39'

在这里插入图片描述

2…PayDemoActivity 活动
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;
import androidx.fragment.app.FragmentActivity;
import com.alibaba.fastjson.JSON;
import com.alipay.sdk.app.EnvUtils;
import com.learn.agg.R;
import com.learn.agg.alipay.AlipayAck;
import com.learn.agg.alipay.AlipayHelper;
import com.learn.agg.alipay.URLInterface;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;
import okhttp3.Call;

/**
 * 重要说明:
 * <p>
 * 这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成;
 * 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;
 * 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;
 */
public class PayDemoActivity extends FragmentActivity {

    /** 商户私钥,pkcs8格式 */
    /** 如下私钥,RSA2_PRIVATE 或者 RSA_PRIVATE 只需要填入一个 */
    /** 如果商户两个都设置了,优先使用 RSA2_PRIVATE */
    /** RSA2_PRIVATE 可以保证商户交易在更加安全的环境下进行,建议使用 RSA2_PRIVATE */
    /** 获取 RSA2_PRIVATE,建议使用支付宝提供的公私钥生成工具生成, */



    public PayDemoActivity() {
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pay_main);
        RadioGroup radioGroup;
        final RadioButton alipay;

        alipay = findViewById(R.id.alipay);
        radioGroup = findViewById(R.id.payWay_choose);
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                if (alipay.getId()==i){

                }

            }
        });

    }

    /**
     * 支付宝支付业务
     *
     * @param v
     */
    public void payV2(View v) {

        /**
         * 这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成;
         * 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;
         * 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;
         *
         * orderInfo的获取必须来自服务端
         * 如果RSA2_PRIVATE RSA_PRIVATE都设置了,那么我是优先选择RSA2_PRIVATE,因为更加安全
         */

        //这里是用OkHttpUtils向服务器发起请求
        
        String url = URLInterface.BASE_URL + "/alipay"; 

        String paymoney = "0.05";//分为单位 1==1元
   
        OkHttpUtils
                .post()
                .url(url)
                .addParams("payMoney", paymoney )
                .build()
                .execute(new StringCallback() {
                    @Override
                    public void onError(Call call, Exception e, int id) {
                        Toast.makeText(PayDemoActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                    @Override
                    public void onResponse(String response, int id) {
                        AlipayAck alipayAck = JSON.parseObject(response, AlipayAck.class);
                        Toast.makeText(PayDemoActivity.this, alipayAck.getMessage(), Toast.LENGTH_SHORT).show();
                        testAliPay(alipayAck.getContent().getOrderString());
                    }
                });
    }

    private void testAliPay(String orderInfo) {
        AlipayHelper mAlipayHelper = new AlipayHelper();
        mAlipayHelper.startAlipay(this, orderInfo, new AlipayHelper.OnPayClickListener() {
            @Override
            public void paySuccess() {
                //支付成功
                Log.d("tag", "paySuccess: 哈哈哈");
                Toast.makeText(PayDemoActivity.this,"支付成功",Toast.LENGTH_LONG).show();
                //支付成功的操作
            }

            @Override
            public void payFailure() {
                //支付失败
                Log.d("tag", "payFailure: ");

            }
        });

    }

}


3.AlipayAck.java
public class AlipayAck extends BaseEntity {

    private ContentBean content;

    public ContentBean getContent() {
        return content;
    }

    public void setContent(ContentBean content) {
        this.content = content;
    }

    public static class ContentBean {


        private String orderString;
        private String out_trade_no;

        public String getOut_trade_no() {
            return out_trade_no;
        }

        public void setOut_trade_no(String out_trade_no) {
            this.out_trade_no = out_trade_no;
        }

        public String getOrderString() {
            return orderString;
        }

        public void setOrderString(String orderString) {
            this.orderString = orderString;
        }
    }
}

4.AlipayHelper.java
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import com.alipay.sdk.app.PayTask;
import java.util.Map;

public class AlipayHelper {
    private static final int SDK_PAY_FLAG = 1;

    private static AlipayHelper mAlipayHelper = new AlipayHelper();

    private OnPayClickListener onPayClickListener;

    //支付成功接口回调
    public interface OnPayClickListener {

        void paySuccess();

        void payFailure();

    }

    public void startAlipay(final Activity activity, final String orderInfo, OnPayClickListener onPayClickListener) {
        if (onPayClickListener == null || activity == null || orderInfo == null) {
            return;
        }

        this.onPayClickListener = onPayClickListener;

        Runnable payRunnable = new Runnable() {
            @Override
            public void run() {
                PayTask alipay = new PayTask(activity);
                Map<String, String> result = alipay.payV2(orderInfo, true);
                Log.i("msp", result.toString());
                Message msg = new Message();
                msg.what = SDK_PAY_FLAG;
                msg.obj = result;
                mHandler.sendMessage(msg);
            }
        };

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

    @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(MyApplication.getContext(), "支付成功", Toast.LENGTH_SHORT).show();
                        if (onPayClickListener != null) {
                            onPayClickListener.paySuccess();
                        }
                    } else {
                        // 该笔订单真实的支付结果,需要依赖服务端的异步通知。
                       // Toast.makeText(MyApplication.getContext(), "支付失败", Toast.LENGTH_SHORT).show();
                        if (onPayClickListener != null) {
                            onPayClickListener.payFailure();
                        }
                    }
                    break;
                }
                default:
                    break;
            }
        }

        ;
    };

}


5.BaseEntity.java
public class BaseEntity {
    private int code;
    private String message;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
6.ExternalFragment.java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import com.learn.agg.R;

public class ExternalFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.pay_external, container, false);
    }
}

7.pay_external.xml

在这里插入图片描述alipay.png

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingTop="12dp">
        <View
            android:layout_width="match_parent"
            android:layout_height="0.1dp"
            android:layout_marginTop="5dp"
            android:background="#000" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="2">
            <RadioGroup
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:id="@+id/payWay_choose">

                <RadioButton
                    android:id="@+id/alipay"
                    android:layout_width="match_parent"
                    android:layout_height="65dp"
                    android:onClick="payV2"
                    android:drawableLeft="@drawable/alipay"
                    android:padding="20dp" />

            </RadioGroup>
        </LinearLayout>
        <View
            android:layout_width="match_parent"
            android:layout_height="0.1dp"
            android:layout_marginTop="5dp"
            android:background="#000" />

    </LinearLayout>

</ScrollView>

在这里插入图片描述

8.PayResult.java
import android.text.TextUtils;
import java.util.Map;

public class PayResult {
    private String resultStatus;
    private String result;
    private String memo;

    public PayResult(Map<String, String> rawResult) {
        if (rawResult == null) {
            return;
        }

        for (String key : rawResult.keySet()) {
            if (TextUtils.equals(key, "resultStatus")) {
                resultStatus = rawResult.get(key);
            } else if (TextUtils.equals(key, "result")) {
                result = rawResult.get(key);
            } else if (TextUtils.equals(key, "memo")) {
                memo = rawResult.get(key);
            }
        }
    }

    @Override
    public String toString() {
        return "resultStatus={" + resultStatus + "};memo={" + memo
                + "};result={" + result + "}";
    }

    /**
     * @return the resultStatus
     */
    public String getResultStatus() {
        return resultStatus;
    }

    /**
     * @return the memo
     */
    public String getMemo() {
        return memo;
    }

    /**
     * @return the result
     */
    public String getResult() {
        return result;
    }
}


9.URLInterface接口
public interface URLInterface {

    String BASE_URL = "http://localhost:8080";//测试服服务器
}
10.pay_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="45dp"
        android:background="@drawable/msp_demo_title_bg"
        android:scaleType="center"
        android:src="@drawable/msp_demo_title"
        tools:ignore="ContentDescription" />

    <fragment
        android:id="@+id/fragment"
        android:name="com.learn.agg.alipay.ExternalFragment"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

在这里插入图片描述msp_demo_title_bg.png

在这里插入图片描述
msp_demo_title.png

11.manifest
  <application
  android:networkSecurityConfig="@xml/network_config" 
  >
    <activity android:name=".act.PayDemoActivity" />

network_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>


完结了。
我已经成功实现了,如果你没有成功的话,可以留言,看看是什么问题导致的…
如果你的PayDemoActivity是主活动,请在manifest加上

  <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一粒程序米

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值