随笔 - 172  文章 - 52  评论 - 6  阅读 - 17万

[java-project-gl]支付

(一支付宝支付)

1、进入“蚂蚁金服开放平台”

https://open.alipay.com/platform/home.htm

2、下载支付宝官方demo,进行配置和测试

文档地址
https://open.alipay.com/platform/home.htm 支付宝&蚂蚁金服开发者平台

https://docs.open.alipay.com/catalog 开发者文档

https://docs.open.alipay.com/270/106291/ 全部文档=>电脑网站支付文档;下载demo

(二内网穿透)

1、简介

内网穿透功能可以允许我们使用外网的网址来访问主机;正常的外网需要访问我们项目的流程是:
1、买服务器并且有公网固定 IP
2、买域名映射到服务器的IP
3、域名需要进行备案和审核

2、使用场景

1、开发测试(微信、支牢)
2、智慧互联
3、远程控制
4、私有云

3、内网穿透的几个常用软件

1、natapp: https://natapp.cn/
2、续断:www.zhexi.tech
3、花生壳:https://www.orav.com/

内网穿透详细配置见: [谷粒商城139P-140P]nginx安装和nginx域名映射

(三)项目实例

配置nginx

[root@localhost ~]# cd /mydata/nginx/conf/conf.d/
[root@localhost conf.d]# vi gulimall.conf

gulimall.conf

server {
    listen       80;
    server_name  gulimall.com  *.gulimall.com zzqzhifubao.free.idcfengye.com;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;
    location /static/ {
        root /usr/share/nginx/html;
    }

    location /payed/ {
        proxy_set_header Host order.gulimall.com;
        proxy_pass http://gulimall;
    }
    location / {
        proxy_set_header Host $host;
        proxy_pass http://gulimall;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

java项目配置:

pom.xml

        <!--    导入支付宝的SDK    -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.9.28.ALL</version>
        </dependency>

支付的html

pay.html

<li>
     <img src="https://img2023.cnblogs.com/blog/1938730/202303/1938730-20230306005655117-1673976072.png" style="weight:auto;height:30px; "alt="">
    <a th:href="'http://order.gulimall.com/payOrder?orderSn='+${submitOrderResp.order.orderSn}">支付宝</a>
 </li>

支付宝页面显示信息的Vo

PayVo.java

package com.atguigu.gulimall.order.vo;

import lombok.Data;

import java.io.Serializable;

@Data
public class PayVo  {
    private String out_trade_no; // 商户订单号 必填
    private String subject; // 订单名称 必填
    private String total_amount;  // 付款金额 必填
    private String body; // 商品描述 可空
}

支付成功后,支付宝返回数据封装的Vo

PayAsyncVo.java

package com.atguigu.gulimall.order.vo;

import lombok.Data;
import lombok.ToString;

import java.util.Date;

@ToString
@Data
public class PayAsyncVo {

    private String gmt_create;
    private String charset;
    private String gmt_payment;
    private Date notify_time;
    private String subject;
    private String sign;
    private String buyer_id;//支付者的id
    private String body;//订单的信息
    private String invoice_amount;//支付金额
    private String version;
    private String notify_id;//通知id
    private String fund_bill_list;
    private String notify_type;//通知类型; trade_status_sync
    private String out_trade_no;//订单号
    private String total_amount;//支付的总额
    private String trade_status;//交易状态  TRADE_SUCCESS
    private String trade_no;//流水号
    private String auth_app_id;//
    private String receipt_amount;//商家收到的款
    private String point_amount;//
    private String app_id;//应用id
    private String buyer_pay_amount;//最终支付的金额
    private String sign_type;//签名类型
    private String seller_id;//商家的id

}

支付配置类

AlipayTemplate.java

package com.atguigu.gulimall.order.config;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;

import com.atguigu.gulimall.order.vo.PayVo;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@ConfigurationProperties(prefix = "alipay")
@Component
@Data
public class AlipayTemplate {

    //在支付宝创建的应用的id
    private String app_id="2021000116675617";
    // 商户私钥,您的PKCS8格式RSA2私钥
    private String merchant_private_key="MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCiyx0/94Esfw46b/pLnc7JhGPzVKRFeWP0/lnvfjgQ1kmRMVzcWrXUueSgIfKfTuLx0BMvFW2jB83mqeJsFRqyOZ3NOy/AlzOsW3qVmgzW1b51HV2l+eCWOHnPeV/xPVmNCFTo91ButKsbl9wDBLM5USXB4VzzT894XM0y8RvQoxRTI5+HWb4tbUmuQfr63bgJsy180ibtlXsvKWSjrHuElc2Qw1DhZkdvuwxSaoiMZGnlix6zZOOzUO3/gJZ9aFu6cFz9XqATNb/xI614tp05jVUcczyVkc+8pmSXJ38my06rrso/QaIoPAhqabjpQn5YKBTyIxThX5KkbsmjK5PpAgMBAAECggEAIF3N1Pf6oMQqKgg1dW9Mu9gsnyaG+qEl9IHVk74+m2pfehScZ9tJJ6BGCmh1eqMOkBFUnxndkHpuv5urPt37TtARxcostlfZmD0f5DqaruQUV+icw/Eoa/WSkmOJZcdS1K2BZEg3n6sgEf5haeA3Wf/+R8vs1RtbHo0k5yn048gXf6nTDRgW1N/RQB5bAbfKwFsm0bhHPInFSdfO3z7WwZya4fzY0X4JLDKXjjr6Br2PzA8l/GbVqLiwK/oQ0SScorb2/OQ+rrbqujb7g+WNXBtR0toATLqcluJWzxsNlO26zF3LDhl0RnX+lajnu3z6DEf7kAhWbgM5P/nseaPEmQKBgQDRrhHilp9ECM2FgfIHBDF1iqd6mYTUHXBHKkmb2xMIkVViSWQ0h3wKMPbdMq9wX+dr3IutySgG+RwRwJxfw+7o99/Hw0tyUaYghATpNt0FRk6aav/e04Gz1zpKeFD7R8YB6OIQnqPqayPM7Vss47WQ0JKrY1nlwfrhqs9QZqBT+wKBgQDGwX36kxGNz3Ycvi3c75WT8x80bEJXeRbnUypZo79UDmqSXVeW+x8Jh582nOkuYWLP30nS2CV7K1OwQz+YiuwcwkIeZ6G0yl7oxAtIOnEWFyV28nI+Tv4MEhTMA9iBb3B/wzhm4GFQykrIe2CQuq5+ddJ6aiBoU+WXBHv7dxZOawKBgBIRLKtYjSqgk4zwcHlYTCazptCyj7ZzPuxy4VrTmqU/WJsadc7s6aw7IdpXdrR5Hwi1PTfhQFixeFCzRwYdbOWYDik5U7PrAySEG6Q4vPyqXTWDCL8bfG6Rmg02psuwGIirl2cVNEyLpM8QmK2ahVeQEUNBUUqx1ztAq5Ji9WenAoGAImpWuhDFNVz7ArcbkeoaaGfsu1MTmbnp8VxBNQxZkOB+K6HmDMqm8St+siIxbkqGpZ/wVIYA13cFIrxCQtOrVr98W29uXLO+A2gO3A7ijgSsBBCvH4LmEoj++OShlKgLPtQ66/VmZGri0Bws+GKa3GLiczf1LJt6Yc/w9/YC8skCgYAdMrPVudv/ZmOyAkzuWrW6nO9WcwVnTwfUz33bW9UtbcS7AJ/0WSX323MzA83J4RVtLt4StdUvTUTAwWJfy6R3k/dhZvXcICFQg5r4cSQWvHAfJ313BieUg3F3TUqeoHh5U/tZDcH0pt9kiVViKV5SbJSx0a/cg5XhTwcTVKe/OA==";
    // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    private String alipay_public_key="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqG9M9q4iEvBUx3cO/hyeF++mpktF+/YEtKBE3Gllo06F3nVYlebECzl4Ydn1hWhK890FVINuha40+eGUyy6vn64PNgany+73NP47J3go1hkCqJfhJvE1py0iKC5U5W22AXZOe32x0QiNDWJpQfOV2m5uxPl66MZ8JuLHTLlGT9PpI3ZqeXNGUm3bfIotJCndaOZiOd479NDusLdV7xyMNgrAXX5tYfwAjGI5UamCZ3GZdtZgP+0jstsOkwl/iijF3VJHsoeesZGdsdIoLmxFt/g9lbYSlkBbJHC0tQ2fZKDr1dvpnOQb264HuCahke8neyHvxgpzZfhC6inchbNQ2QIDAQAB";
    // 服务器[异步通知]页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    // 支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息
    private String notify_url="http://zzqzhifubao.free.idcfengye.com/payed/notify";

    // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    //同步通知,支付成功,一般跳转到成功页
    private String return_url="http://member.gulimall.com/memberOrder.html";

    // 签名方式
    private String sign_type = "RSA2";

    // 字符编码格式
    private String charset = "utf-8";
	
    //支付页面超时时间
    private String timeout = "30m";

    // 支付宝网关; https://openapi.alipaydev.com/gateway.do
    private String gatewayUrl="https://openapi.alipaydev.com/gateway.do";

    public String pay(PayVo vo) throws AlipayApiException {

        //AlipayClient alipayClient = new DefaultAlipayClient(AlipayTemplate.gatewayUrl, AlipayTemplate.app_id, AlipayTemplate.merchant_private_key, "json", AlipayTemplate.charset, AlipayTemplate.alipay_public_key, AlipayTemplate.sign_type);
        //1、根据支付宝的配置生成一个支付客户端
        AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl,
                app_id, merchant_private_key, "json",
                charset, alipay_public_key, sign_type);

        //2、创建一个支付请求 //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(return_url);
        alipayRequest.setNotifyUrl(notify_url);

        //商户订单号,商户网站订单系统中唯一订单号,必填
        String out_trade_no = vo.getOut_trade_no();
        //付款金额,必填
        String total_amount = vo.getTotal_amount();
        //订单名称,必填
        String subject = vo.getSubject();
        //商品描述,可空
        String body = vo.getBody();

        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"body\":\""+ body +"\","
                + "\"timeout_express\":\""+timeout+"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        String result = alipayClient.pageExecute(alipayRequest).getBody();

        //会收到支付宝的响应,响应的是一个页面,只要浏览器显示这个页面,就会自动来到支付宝的收银台页面
        System.out.println("支付宝的响应:"+result);

        return result;

    }
}

支付的Controller

PayWebController.java

package com.atguigu.gulimall.order.web;

import com.alipay.api.AlipayApiException;
import com.atguigu.gulimall.order.config.AlipayTemplate;
import com.atguigu.gulimall.order.service.OrderService;
import com.atguigu.gulimall.order.vo.PayVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class PayWebController {

    @Autowired
    AlipayTemplate alipayTemplate;

    @Autowired
    OrderService orderService;

    @ResponseBody
    @GetMapping(value = "/payOrder",produces = "text/html")
    public String payOrder(@RequestParam("orderSn") String orderSn) throws AlipayApiException {
//        PayVo payVo = new PayVo();
//        payVo.setBody();  //订单的备注
//        payVo.setOut_trade_no();  //订单号
//        payVo.setSubject();  //订单的主题
//        payVo.setTotal_amount();  //订单的金额
        PayVo payVo = orderService.getOrderPay(orderSn);
        //返回的是一个页面.将此页面直接交给浏览器就行
        String pay = alipayTemplate.pay(payVo);
        System.out.println(pay);
        return pay;
    }
}

支付 的Service的实现

获取支付商品的基本信息,显示在支付宝付款界面展示

getOrderPay.java

    /**
     * 获取当前订单的支付信息
     * @param orderSn
     * @return
     */
    @Override
    public PayVo getOrderPay(String orderSn) {
        PayVo payVo = new PayVo();
        OrderEntity order = this.getOrderByOrderSn(orderSn);
        List<OrderItemEntity> order_sn = orderItemService.list(new QueryWrapper<OrderItemEntity>().eq("order_sn", orderSn));
        OrderItemEntity entity = order_sn.get(0);

        //保留两位小数点,向上取值
        BigDecimal bigDecimal = order.getPayAmount().setScale(2, BigDecimal.ROUND_UP);
        //System.out.println();
        payVo.setTotal_amount(bigDecimal.toString());
        payVo.setOut_trade_no(order.getOrderSn());

        payVo.setSubject(entity.getSkuName());
        payVo.setBody(entity.getSkuAttrsVals());

        System.out.println("向支付宝页面传输的数据为 :" + "总金额" + bigDecimal.toString()+"订单号" + order.getOrderSn() + "货物名字" + entity.getSkuName());

        return payVo;
    }

支付成功后写入数据库

handleOayResult.java

    /**
     * 处理支付宝的支付结果
     * @param vo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String handleOayResult(PayAsyncVo vo) {
        //保存交易流水信息
        PaymentInfoEntity infoEntitynfo = new PaymentInfoEntity();
        infoEntitynfo.setOrderSn(vo.getOut_trade_no());
        infoEntitynfo.setAlipayTradeNo(vo.getTrade_no());
//        infoEntitynfo.setTotalAmount(new BigDecimal(vo.getBuyer_pay_amount()));
//        infoEntitynfo.setSubject(vo.getBody());
        infoEntitynfo.setPaymentStatus(vo.getTrade_status());
//        infoEntitynfo.setCreateTime(new Date());
        infoEntitynfo.setCallbackTime(vo.getNotify_time());
        //添加到数据库中
        paymentInfoService.save(infoEntitynfo);

        //修改订单状态
        //获取当前状态
        String tradeStatus = vo.getTrade_status();

        if (tradeStatus.equals("TRADE_SUCCESS") || tradeStatus.equals("TRADE_FINISHED")) {
            //支付成功状态
            String orderSn = vo.getOut_trade_no(); //获取订单号
            this.baseMapper.updateOrderStatus(orderSn,OrderStatusEnum.PAYED.getCode());
        }

        return "success";
    }

posted on   共感的艺术  阅读(189)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2020-03-09 人形词云,根据图片黑白形状绘制词云
2020-03-09 汉化的simple词云
2020-03-09 对于数据的平均值处理
2020-03-09 文字替换成函数返回数字进行排序
2020-03-09 校验
2020-03-09 Python:使用lambda对列表(list)和字典(dict)排序
2020-03-09 python中的数据排序
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示