前面三个章节是学习和摸索过程,现在进入主题,生成收款码。还是用沙箱环境来调试。
1.新建windowsform程序,根据章节三,导入支付宝SDK。
2.下载官方当面付DEMO程序:当面付DEMO
3.按照下图打开项目:
这是WEB版本的代码,由于官方的DEMO是集成所有接口的,会出现代码重复和代码岑余,所以不直接使用官方DEMO,只选取需要的部分,打开如下图所示界面:
生成收款码的接口程序就是这里,如下:
///
/// 功能:预下单接口接入页
/// 日期:2016-12-27
/// 说明:
/// 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
/// 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
///
/// /注意///
/// 如果您在接口集成过程中遇到问题,可以按照下面的途径来解决
/// 1、支持中心(https://support.open.alipay.com/alipay/support/index.htm),提交申请集成协助,我们会有专业的技术工程师主动联系您协助解决
/// 2、开发者论坛(https://openclub.alipay.com/)
///
public partial class PreCreate : System.Web.UI.Page
{
private LogHelper log = new LogHelper(AppDomain.CurrentDomain.BaseDirectory + "/log/log.txt");
IAlipayTradeService serviceClient = F2FBiz.CreateClientInstance(Config.serverUrl, Config.appId, Config.merchant_private_key, Config.version,
Config.sign_type, Config.alipay_public_key, Config.charset);
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Alipay_RSA_Submit(object sender, EventArgs e)
{
AlipayTradePrecreateContentBuilder builder = BuildPrecreateContent();
string out_trade_no = builder.out_trade_no;
//如果需要接收扫码支付异步通知,那么请把下面两行注释代替本行。
//推荐使用轮询撤销机制,不推荐使用异步通知,避免单边账问题发生。
AlipayF2FPrecreateResult precreateResult = serviceClient.tradePrecreate(builder);
//string notify_url = "http://10.5.21.14/notify_url.aspx"; //商户接收异步通知的地址
//AlipayF2FPrecreateResult precreateResult = serviceClient.tradePrecreate(builder, notify_url);
//以下返回结果的处理供参考。
//payResponse.QrCode即二维码对于的链接
//将链接用二维码工具生成二维码打印出来,顾客可以用支付宝钱包扫码支付。
string result = "";
switch (precreateResult.Status)
{
case ResultEnum.SUCCESS:
DoWaitProcess(precreateResult);
break;
case ResultEnum.FAILED:
result = precreateResult.response.Body;
Response.Redirect("result.aspx?Text=" + result);
break;
case ResultEnum.UNKNOWN:
if (precreateResult.response == null)
{
result = "配置或网络异常,请检查后重试";
}
else
{
result = "系统异常,请更新外部订单后重新发起请求";
}
Response.Redirect("result.aspx?Text=" + result);
break;
}
}
///
/// 构造支付请求数据
///
/// 请求数据集
private AlipayTradePrecreateContentBuilder BuildPrecreateContent()
{
//线上联调时,请输入真实的外部订单号。
string out_trade_no = "";
if (String.IsNullOrEmpty(WIDout_request_no.Text.Trim()))
{
out_trade_no = System.DateTime.Now.ToString("yyyyMMddHHmmss") + "0000" + (new Random()).Next(1, 10000).ToString();
}
else
{
out_trade_no = WIDout_request_no.Text.Trim();
}
AlipayTradePrecreateContentBuilder builder = new AlipayTradePrecreateContentBuilder();
//收款账号
builder.seller_id = Config.pid;
//订单编号
builder.out_trade_no = out_trade_no;
//订单总金额
builder.total_amount = WIDtotal_fee.Text.Trim();
//参与优惠计算的金额
//builder.discountable_amount = "";
//不参与优惠计算的金额
//builder.undiscountable_amount = "";
//订单名称
builder.subject = WIDsubject.Text.Trim();
//自定义超时时间
builder.timeout_express = "5m";
//订单描述
builder.body = "";
//门店编号,很重要的参数,可以用作之后的营销
builder.store_id = "test store id";
//操作员编号,很重要的参数,可以用作之后的营销
builder.operator_id = "test";
//传入商品信息详情
List<GoodsInfo> gList = new List<GoodsInfo>();
GoodsInfo goods = new GoodsInfo();
goods.goods_id = "goods id";
goods.goods_name = "goods name";
goods.price = "0.01";
goods.quantity = "1";
gList.Add(goods);
builder.goods_detail = gList;
//系统商接入可以填此参数用作返佣
//ExtendParams exParam = new ExtendParams();
//exParam.sysServiceProviderId = "20880000000000";
//builder.extendParams = exParam;
return builder;
}
///
/// 生成二维码并展示到页面上
///
/// 二维码串
private void DoWaitProcess( AlipayF2FPrecreateResult precreateResult )
{
//打印出 preResponse.QrCode 对应的条码
Bitmap bt;
string enCodeString = precreateResult.response.QrCode;
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H;
qrCodeEncoder.QRCodeScale = 3;
qrCodeEncoder.QRCodeVersion = 8;
bt = qrCodeEncoder.Encode(enCodeString, Encoding.UTF8);
string filename = System.DateTime.Now.ToString("yyyyMMddHHmmss") + "0000" + (new Random()).Next(1, 10000).ToString()
+ ".jpg";
bt.Save(Server.MapPath("~/images/") + filename);
this.Image1.ImageUrl = "~/images/" + filename;
//轮询订单结果
//根据业务需要,选择是否新起线程进行轮询
//ParameterizedThreadStart ParStart = new ParameterizedThreadStart(LoopQuery);
//Thread myThread = new Thread(ParStart);
//object o = precreateResult.response.OutTradeNo;
//myThread.Start(o);
}
///
/// 轮询
///
/// 订单号
public void LoopQuery(object o)
{
AlipayF2FQueryResult queryResult = new AlipayF2FQueryResult();
int count = 100;
int interval = 10000;
string out_trade_no = o.ToString();
for (int i = 1; i <= count; i++)
{
Thread.Sleep(interval);
queryResult = serviceClient.tradeQuery(out_trade_no);
if (queryResult != null)
{
if (queryResult.Status == ResultEnum.SUCCESS)
{
DoSuccessProcess(queryResult);
return;
}
}
}
DoFailedProcess(queryResult);
}
///
/// 请添加支付成功后的处理
///
private void DoSuccessProcess(AlipayF2FQueryResult queryResult)
{
//支付成功,请更新相应单据
log.WriteLine("扫码支付成功:外部订单号" + queryResult.response.OutTradeNo);
}
///
/// 请添加支付失败后的处理
///
private void DoFailedProcess(AlipayF2FQueryResult queryResult)
{
//支付失败,请更新相应单据
}
然后根据自己的沙箱账号信息进行修改。验证代码,若成功,则支付宝会打印二维码的链接,例如支付宝反馈如下:
{
"alipay_trade_precreate_response":{
"code":"10000","msg":"Success","out_trade_no":"20210122023434655412652021-01-13 17:32:43","qr_code":"https:\/\/qr.alipay.com\/bax07049mbi0yh6v2avuz000c"},"sign":"XAZYYP54rYRt2EpJ5UNnFVaIwPas4L40UgZ6ftdJhMOyQGwzV7ejjnYfQosQjn8UiDfi/TQ25FfdvfexoumQSbEoc8TZsORlPvkZy/C2c6HSR543TIumjol52WhHgurltYbtKsI5+SO78mspcncoxwCgrS+ZwPCA2vJqf14ldbXdGAIbveENMrMzlWlm73H0/rp2KpdInjEP0BKwWP+bfImW1ZvicGLE2f6Ul4KDsk4CuSYPXsajT6ROAl/0qXfr5WjqzkOv71NewTzzMNqM2RS8n01rrfKmF6AcpEM9/U+vpoAoOOCTojKEGh/dPB2UQGDG0Wi1ZsFIwuoFLSGbP1T9ifvGXJWfR8w=="}
其中需要生成二维码的链接是:“qr_code”:后面跟着的链接"https://qr.alipay.com/bax07049mbi0yh6va2vuz000c",去掉‘ ” ’,去掉‘ \ ’,最后的字符串生成二维码即可。(”https://qr.alipay.com/bax07049mbi0yh6va2vuz000c”)
4.调用ThoughtWorks.QRCode.dll生成二维码
下载ThoughtWorks.QRCode.dll;ThoughtWorks.QRCode.dll
导入DLL到代码;
生成二维码代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using System.Drawing;
using System.Text;
using ThoughtWorks.QRCode.Codec;
using System.IO;
namespace App.Web.APIControllers
{
///
/// 生成二维码
/// public class QRCodeController : Controller
{
///
/// 生成二维码
///
/// 要生成二维码的文字
///
[HttpGet]
[AllowAnonymous]
public string QRCode(string enCodeString)
{
System.Drawing.Bitmap bt;
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;//编码方式(注意:BYTE能支持中文,ALPHA_NUMERIC扫描出来的都是数字)
qrCodeEncoder.QRCodeScale = 10;//大小(值越大生成的二维码图片像素越高)
qrCodeEncoder.QRCodeVersion = 0;//版本(注意:设置为0主要是防止编码的字符串太长时发生错误)
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;//错误效验、错误更正(有4个等级)
qrCodeEncoder.QRCodeBackgroundColor = Color.White;//背景色
qrCodeEncoder.QRCodeForegroundColor = Color.Black;//前景色
bt = qrCodeEncoder.Encode(enCodeString, Encoding.UTF8);
string filename = enCodeString;// "code";
string file_path = AppDomain.CurrentDomain.BaseDirectory + "QRCode\\";
string codeUrl = file_path + filename + ".jpg";
//根据文件名称,自动建立对应目录
if (!System.IO.Directory.Exists(file_path))
{
System.IO.Directory.CreateDirectory(file_path);
}
防止内容重复,导致名称重复问题,
若要每次更新,可去掉本段代码 ↓↓↓↓↓
//int i = 1;
//while (System.IO.File.Exists(codeUrl))
//{
// string _filename = filename + "("+i+")";
// codeUrl = file_path + _filename + ".jpg";
// i++;
//}
↑↑↑↑↑↑↑
bt.Save(codeUrl);//保存图片
return codeUrl;
}
///
/// 生成二维码【方法二】
///
/// 尺寸4-15
/// 复杂级别3-12
/// 容错量"H","L","M","Q"
/// 二维码信息
///
[HttpGet]
[AllowAnonymous]
public string CreateEQcoder(int qrCodeScale, int qrCodeVersion, string qrCodeErrorCorrect, string enCodeString)
{
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
qrCodeEncoder.QRCodeScale = qrCodeScale;
qrCodeEncoder.QRCodeVersion = qrCodeVersion;
switch (qrCodeErrorCorrect)
{
case "H":
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H;
break;
case "L":
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.L;
break;
case "M":
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
break;
case "Q":
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.Q;
break;
}
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.L;
Bitmap bmPhoto = qrCodeEncoder.Encode(enCodeString, System.Text.Encoding.GetEncoding("UTF-8"));
string fileName = enCodeString+"_"+ qrCodeScale+"_"+qrCodeVersion+"_"+ qrCodeErrorCorrect;
string file_path = AppDomain.CurrentDomain.BaseDirectory + "QRCode\\";
string savePath = file_path + fileName + ".jpg";
try
{
if (!Directory.Exists(file_path))
{
Directory.CreateDirectory(file_path);
}
//防止内容重复,导致名称重复问题,若要每次更新,可去掉本段代码 ↓↓↓↓↓
int i = 1;
while (System.IO.File.Exists(savePath))
{
string _filename = fileName + "(" + i + ")";
savePath = file_path + _filename + ".jpg";
i++;
}
//↑↑↑↑↑↑↑
bmPhoto.Save(savePath);
bmPhoto.Dispose();
return savePath ;
}
catch (Exception)
{
return "";
}
finally
{
bmPhoto.Dispose();
}
}
}
}
根据自己情况适当修改。
5.最终将支付宝返回的二维码链接生成二维码即可。我的界面大致如下: