支付宝支付、退款(网站应用)

1.1  第一步:创建应用

1.      您需要先去蚂蚁金服开放平台(open.alipay.com),在开发者中心创建登记您的应用,此时您将获得应用唯一标识(APPID);

2.      请在【功能信息】中点击【添加功能】,选择【电脑网站支付】;

3.      提交审核,等待审核通过,该应用正式可以使用。

1.2  第二步:配置密钥

开发者调用接口前需要先生成RSA密钥,RSA密钥包含应用私钥(APP_PRIVATE_KEY)、应用公钥(APP_PUBLIC_KEY)。生成密钥后在开放平台管理中心进行密钥配置,配置完成后可以获取支付宝公钥(ALIPAY_PUBLIC_KEY)

1.3 搭建和配置开发环境

1.      下载服务端SDK以及相关支付代码

https://docs.open.alipay.com/270/106291/

2.       接口调用配置

1.4  接口调用

 支付接口(alipay.trade.page.pay


 退款接口(alipay.trade.refund


代码如下:

AlipayConfig 类

package com.xgh.test.config;


import java.io.FileWriter;
import java.io.IOException;


/* *
 *类名:AlipayConfig
 *功能:基础配置类
 *详细:设置帐户有关信息及返回路径
 *说明:
 *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
 */


public class AlipayConfig {

//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id = "";

// 商户私钥,您的PKCS8格式RSA2私钥
    public static String merchant_private_key = "";

// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    public static String alipay_public_key = "";


// 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String notify_url = "";



// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String return_url = "";


// 签名方式
public static String sign_type = "RSA2"; 

// 字符编码格式
public static String charset = "utf-8";

// 支付宝网关
public static String gatewayUrl = "https://openapi.alipay.com/gateway.do";

// 支付宝网关
public static String log_path = "C:\\";



//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑


    /** 
     * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
     * @param sWord 要写入日志里的文本内容
     */
    public static void logResult(String sWord) {
        FileWriter writer = null;
        try {
            writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
            writer.write(sWord);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}



Alipay类


package com.xgh.test.controller;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;


import com.alibaba.fastjson.JSONObject;
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.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.xgh.test.config.AlipayConfig;


@Controller
public class Alipay {

/**
* 执行支付
* @throws IOException 
* @throws AlipayApiException 
* out_trade_no 商户订单号,商户网站订单系统中唯一订单号,必填
* total_amount 付款金额,必填
* subject 订单名称,必填
* body 商品描述,可空

*/
@RequestMapping("pay")
public String pay(
@RequestParam("WIDout_trade_no") String out_trade_no,
@RequestParam("WIDsubject") String subject,
@RequestParam("WIDtotal_amount") String total_amount,
@RequestParam("WIDbody") String body,
Model mode,
HttpServletRequest request,
HttpSession session,
HttpServletResponse response) throws IOException, AlipayApiException {

//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

//设置请求参数
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(AlipayConfig.return_url);
alipayRequest.setNotifyUrl(AlipayConfig.notify_url);


//进行转换码
subject = new String(subject.getBytes("ISO-8859-1"), "utf-8");
body = new String(body.getBytes("ISO-8859-1"), "utf-8");

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

//若想给BizContent增加其他可选请求参数,以增加自定义超时时间参数timeout_express来举例说明
//alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\"," 
// + "\"total_amount\":\""+ total_amount +"\"," 
// + "\"subject\":\""+ subject +"\"," 
// + "\"body\":\""+ body +"\"," 
// + "\"timeout_express\":\"10m\"," 
// + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
//请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节

//请求
String result = alipayClient.pageExecute(alipayRequest).getBody();


mode.addAttribute("result", result);

return "truePay";

}


/**当用户确认支付的时候同步返回参数信息
* 支付宝服务器同步通知
* @throws AlipayApiException 
* @throws IOException 
*/
@RequestMapping("returnCallBack")
public String  returnCallBack(
HttpServletRequest request,
HttpSession session,
HttpServletResponse response,
Model model) throws AlipayApiException, IOException {

String str = null;

String result = null;
//获取支付宝GET过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map<String,String[]> requestParams = request.getParameterMap();
for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
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] + ",";
}
//乱码解决,这段代码在出现乱码时使用
valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}

//调用SDK验证签名
boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); 


//——请在这里编写您的程序(以下代码仅作参考)
if(signVerified) {
//商户订单号
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

//支付宝交易号
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

//付款金额
String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");

result =  "trade_no:"+trade_no+"<br/>out_trade_no:"+out_trade_no+"<br/>total_amount:"+total_amount;
result=new String(result.getBytes("ISO-8859-1"),"utf-8");

str = "product";

}else {
str = "err";
response.getWriter().println("验签失败");
}

model.addAttribute("result", result);

return str;

}

/**
* 支付宝服务器异步通知
* @param request
* @param session
* @param response
* @throws AlipayApiException
* @throws IOException
*/
@RequestMapping("notifyCallBack")
public void notifyCallBack(
HttpServletRequest request,
HttpSession session,
HttpServletResponse response) throws AlipayApiException, IOException {

//获取支付宝POST过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map<String,String[]> requestParams = request.getParameterMap();
for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
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] + ",";
}
//乱码解决,这段代码在出现乱码时使用
valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}

//调用SDK验证签名
boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
//——请在这里编写您的程序(以下代码仅作参考)——


/* 实际验证过程建议商户务必添加以下校验:
1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
4、验证app_id是否为该商户本身。
*/
if(signVerified) {//验证成功
//商户订单号
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

//支付宝交易号
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

//交易状态
String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");

//交易状态枚举值
//WAIT_BUYER_PAY 交易创建,等待买家付款
//TRADE_CLOSED 未付款交易超时关闭,或支付完成后全额退款
//TRADE_SUCCESS 交易支付成功
//TRADE_FINISHED 交易结束,不可退款

if(trade_status.equals("TRADE_FINISHED")){
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序

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

//注意:
//付款完成后,支付宝系统发送该交易状态通知,到此地方执行相关业务处理
}

response.getWriter().println("success");

}else {//验证失败
response.getWriter().println("fail");
}
}


/**
* 退款
* @return
* @throws AlipayApiException 
* @throws UnsupportedEncodingException 
* out_trade_no,//商户订单号,商户网站订单系统中唯一订单号
* trade_no,//支付宝交易号
* refund_amount,//需要退款的金额,该金额不能大于订单金额,必填
* refund_reason,//退款的原因说明
* out_request_no,//标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传
*/
@RequestMapping("refund")
public String refund(
@RequestParam(value="WIDTRout_trade_no",required=false) String out_trade_no,//商户订单号,商户网站订单系统中唯一订单号
@RequestParam(value="WIDTRtrade_no",required=false) String trade_no,//支付宝交易号
@RequestParam("WIDTRrefund_amount") String refund_amount,//需要退款的金额,该金额不能大于订单金额,必填
@RequestParam("WIDTRrefund_reason") String refund_reason,//退款的原因说明
@RequestParam("WIDTRout_request_no") String out_request_no,//标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传
HttpServletRequest request,
HttpSession session,
Model mode,
HttpServletResponse response) throws AlipayApiException, UnsupportedEncodingException {

//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

//设置请求参数
AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();

alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\"," 
+ "\"trade_no\":\""+ trade_no +"\"," 
+ "\"refund_amount\":\""+ refund_amount +"\"," 
+ "\"refund_reason\":\""+ new String(refund_reason.getBytes("ISO-8859-1"),"UTF-8") +"\"," 
+ "\"out_request_no\":\""+ new String(out_request_no.getBytes("ISO-8859-1"),"UTF-8") +"\"}");

//请求并获取返回过来的消息
String result = alipayClient.execute(alipayRequest).getBody();

//把从请求过来的消息,转换为json数据
JSONObject resultJsonAll  = JSONObject.parseObject(result);

JSONObject results = JSONObject.parseObject(resultJsonAll.getString("alipay_trade_refund_response"));

//获取退款消息
String mess = results.getString("msg");
//获取商户订单号
String re_out_trade_no = results.getString("out_trade_no");
//获取交易号
String re_trade_no = results.getString("trade_no");
//获取退款金额
String refund_fee = results.getString("refund_fee");
//获取退至账户
String buyer_logon_id = results.getString("buyer_logon_id");

mode.addAttribute("mess", mess);
mode.addAttribute("refund_fee", refund_fee);
mode.addAttribute("buyer_logon_id", buyer_logon_id);
//如果返回过来的消息等于Success 则调用退款接口成功
if("Success".equals(mess)) {
return "refund";
}else {
return "err";
}
}


}
此致,jsp页面就不贴啦~~请原谅..





  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值