codecamp

支付宝小程序 服务端·当面付 DEMO

Demo 运行环境

  • JAVA Demo 适用于 JDK 版本 1.6 ,Tomcat 版本 6.0。
  • PHP Demo 适用于 PHP 5.5 以上。
  • .Net Demo 适用于 .net framework 3.5以上;visual studio 2010以上。

注意:Demo 仅供参考,实际开发中需要结合具体业务场景修改使用。更多接入详情参见 当面付

使用说明

以 JAVA Demo 为例,本示例仅在支付宝标准 SDK 的基础上再做了一层封装, 即 JAVA 版本 Demo 中 alipay-trade-sdk.jar。

下载

支付宝提供了如下语言当面付 Demo 示例,开发者可下载使用。

JAVA 版 DEMO
.NET 版 DEMO
PHP 版 DEMO

直接运行 Demo 步骤如下

  1. 下载 demo 导入 TradePayDemo。
  2. 根据当面付指引修改配置文件 zfbinfo.properties。
  3. 运行 Main.java 中的 Main 方法。

Main.java 方法介绍

public static void main(String[] args) {
        Main main = new Main();


        // 系统商商测试交易保障接口api
        main.test_monitor_sys();


        // POS厂商测试交易保障接口api
        main.test_monitor_pos();


        // 测试交易保障接口调度
        main.test_monitor_schedule_logic();


        // 测试当面付2.0支付(使用未集成交易保障接口的当面付2.0服务)
        main.test_trade_pay(tradeService);


        // 测试查询当面付2.0交易
        main.test_trade_query();


        // 测试当面付2.0退货
        main.test_trade_refund();


        // 测试当面付2.0生成支付二维码
        main.test_trade_precreate();
    }

集成至商户系统步骤如下

  1. 拷贝 java 目录下的 Main.java 至系统商源代码目录。
  2. 将 lib 目录下所有 jar 文件添加至系统商 lib 目录。
  3. 拷贝 resources 目录下的配置文件至系统商 classpath 根目录。
  4. 在系统商项目中运行 Main 方法,确认集成无误。
  5. 系统商使用 Main 方法中的调用样例进行商户端系统开发。

功能说明

TradePayDemo 代码结构

├─src

│ └─main

│ ├─java

│ ├─com

│ ├─alipay

│ ├─demo

│ ├─trade

│ ├─Main.java 当面付2.0调用范例

│ ├─lib 依赖类库

│ ├─alipay-sdk-java20150625220051.jar

│ ├─alipay-trade-sdk.jar TradePaySDK创建的lib

│ ├─commons-codec-1.10.jar

│ ├─commons-configuration-1.10.jar

│ ├─commons-lang-2.6.jar

│ ├─commons-logging-1.1.1.jar

│ ├─core-2.1.jar

│ ├─gson-2.3.1.jar

│ ├─gson-2.3.1.jar

│ └─resources

│ ├─zfbinfo.properties 配置文件,调用 Main 方法之前请确认配置文件是否已正确配置

AlipayTradeService 对应接口说明

public interface AlipayTradeService {
    // 当面付2.0流程支付    public AlipayF2FPayResult tradePay(AlipayTradePayContentBuilder builder);
    // 当面付2.0消费查询    public AlipayF2FQueryResult queryTradeResult(String outTradeNo);
    // 当面付2.0消费退款    public AlipayF2FRefundResult tradeRefund(AlipayTradeRefundContentBuilder builder);
    // 当面付2.0预下单(生成二维码)public AlipayF2FPrecreateResult tradePrecreate(AlipayTradePrecreateContentBuilder builder);}

条码支付

demo 封装支付宝 SDK,提供了条码付支付、查询、退款 (条码支付)功能,可以给收银系统界面直接调用。

支付接口流程

条码支付.png

支付结果查询接口流程

查询接口流程.png

退款接口流程

退款接口流程.png

扫码支付(不含异步通知)

预下单(扫码支付)接口流程

扫码支付.png

扫码支付结果查询

方案一:采用 条码支付 > 查询接口流程

方案二: 采用轮询逻辑

扫码付轮询.png

示例代码:

alipay-trade-sdk.jar 中提供了轮询 demo,详情参见 com.alipay.demo.trade.service.impl.AbsAlipayTradeService.loopQueryResult。

    // 轮询查询订单支付结果
    protected AlipayTradeQueryResponse loopQueryResult(AlipayTradeQueryRequestBuilder builder) {
        AlipayTradeQueryResponse queryResult = null;
        for (int i = 0; i < Configs.getMaxQueryRetry(); i++) {
            Utils.sleep(Configs.getQueryDuration());


            AlipayTradeQueryResponse response = tradeQuery(builder);
            if (response != null) {
                if (stopQuery(response)) {
                    return response;
                }
                queryResult = response;
            }
        }
        return queryResult;
    }

附:TradePaySDK 代码结构

alipay-trade-sdk.jar 结构说明:

src

-- main

|-- java

| -- com

| -- alipay

| |-- api 服务保障接口数据模型,以后会迁移回底层 alipay sdk

| | |-- request

| | | -- AlipayHeartbeatSyncRequest.java

| | -- response

| | -- AlipayHeartbeatSynResponse.java

| -- demo

| -- trade

| |-- config

| | |-- Configs.java 配置文件,解析properties文件

| | -- Constants.java 常量定义

| |-- model

| | |-- ExtendParams.java 扩展参数

| | |-- GoodsDetail.java

| | |-- TradeStatus.java

| | |-- builder 当面付2.0请求包

| | | |-- AlipayHeartbeatSyncContentBuilder.java 服务保障接口请求bizContent结构体

| | | |-- AlipayTradePayContentBuilder.java 条码支付请求bizContent结构体

| | | |-- AlipayTradePrecreateContentBuilder.java 扫码支付(产生二维码)请求bizContent结构体

| | | |-- AlipayTradeQueryCententBuilder.java 当面付2.0查询请求bizContent结构体

| | | |-- AlipayTradeRefundContentBuilder.java 当面付2.0退款请求bizContent结构体

| | | -- RequestBuilder.java 当面付2.0请求抽象类

| | |-- hb 服务保障接口数据模型

| | | |-- EquipStatus.java

| | | |-- EquipStatusAdapter.java

| | | |-- ExceptionInfo.java

| | | |-- ExceptionInfoAdapter.java

| | | |-- Product.java

| | | |-- TradeInfo.java

| | | |-- TradeStatus.java

| | | -- Type.java

| | -- result 当面付2.0应答包

| | |-- AlipayF2FPayResult.java 当面付2.0支付应答

| | |-- AlipayF2FPrecreateResult.java 当面付2.0预下单(产生二维码)应答

| | |-- AlipayF2FQueryResult.java 当面付2.0查询应答

| | |-- AlipayF2FRefundResult.java 当面付2.0退货应答

| | -- Result.java

| |-- service

| | |-- AlipayTradeService.java 当面付2.0服务接口

| | -- impl

| | -- AlipayTradeServiceImpl.java 当面付2.0具体实现

| -- utils

| |-- GsonFactory.java 使用了gson序列化

| |-- Utils.java 杂物工具类

| -- ZxingUtils.java 使用了zxing库进行二维码的生成

-- lib 依赖类库

​ |-- alipay-sdk-java20150625220051.jar 支付宝sdk底层实现lib

​ |-- commons-codec-1.10.jar

​ |-- commons-configuration-1.10.jar

​ |-- commons-lang-2.6.jar

​ |-- commons-logging-1.1.1.jar

​ |-- core-2.1.jar

​ |-- gson-2.3.1.jar

​ -- hamcrest-core-1.3.jar

常见问题

Q:扫码支付、统一下单 + JSAPI 唤起收银台支付后,支付成功异步通知如何处理?

  1. 商户需要验证该通知数据中的 out_trade_no 是否为商户系统中创建的订单号;
  2. 判断 total_amount 是否确实为该订单的实际金额(即商户订单创建时的金额);
  3. 校验通知中的 seller_id(或者seller_email) 是否为该笔交易对应的操作方(一个商户可能有多个 seller_id/seller_email);
  4. 验证接口调用方的 app_id。
支付宝小程序 服务端·概述
支付宝小程序 服务端·生活号(原服务窗)DEMO
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

支付宝小程序开发文档

支付宝小程序 快速示例

支付宝小程序 小程序快速示例

支付宝小程序 框架

支付宝小程序 组件

支付宝小程序组件 基础组件

支付宝小程序组件 无障碍访问

支付宝小程序 扩展组件

支付宝小程序扩展组件 UI组件

支付宝小程序 API

支付宝小程序 开发工具

支付宝小程序 云服务

支付宝小程序 Serverless

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }