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

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”>

4.0.0

com.example

demo

0.0.1-SNAPSHOT

jar

demo

Demo project for Spring Boot

org.springframework.boot

spring-boot-starter-parent

1.5.8.RELEASE

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<java.version>1.8</java.version>

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

test

org.springframework.boot

spring-boot-maven-plugin

服务器到这就完成啦。

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;

/**

  • 重要说明:

  • 这里只是为了方便直接向商户展示支付宝的整个支付流程;所以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” />

<View

android:layout_width=“match_parent”

android:layout_height=“0.1dp”

android:layout_marginTop=“5dp”

android:background=“#000” />

在这里插入图片描述

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” />

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

在这里插入图片描述

msp_demo_title.png

11.manifest

<application

android:networkSecurityConfig=“@xml/network_config”

network_config.xml

<?xml version="1.0" encoding="utf-8"?> **自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

相信它会给大家带来很多收获:

img

当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。

  • 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!
  • 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。

当我们在抱怨环境,抱怨怀才不遇的时候,没有别的原因,一定是你做的还不够好!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-npBRPUgD-1712424194147)]

[外链图片转存中…(img-FQ8BGWPp-1712424194148)]

[外链图片转存中…(img-EiOdJEAG-1712424194148)]

[外链图片转存中…(img-OMll3Yk1-1712424194148)]

[外链图片转存中…(img-yNdD2Jfo-1712424194149)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

相信它会给大家带来很多收获:

[外链图片转存中…(img-Z3G2yVTq-1712424194150)]

当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。

  • 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!
  • 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。

当我们在抱怨环境,抱怨怀才不遇的时候,没有别的原因,一定是你做的还不够好!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值