Skip to content
hiihellox10 edited this page May 14, 2017 · 15 revisions

如何使用


第一步页面的编码配置

因为部分支付网关的编码仅支持GB2312,为了能够支持多个支付网关所以所有支付网关统一使用GB2312编码。创建支付网关订单的页面跟接收支付网关支付通知的页面均使用GB2312编码。如果使用其他编码可能会因为乱码而造成无法正常创建支付订单和识别支付网关的支付通知。

如果你的程序需要使用其它编码而不能使用GB2312编码,你可以在程序里新建一个用于放置创建支付订单跟接受网关通知页面的新文件夹。然后将创建支付订单跟接受网关通知的页面放置在这个文件夹中,接着这个文件夹中增加一个Web.config文件,修改Web.config文件。在的configuration/system.web节点中增加下面的代码,这样就可以使得只有这个文件夹中的页面使用GB2312编码,而其他页面将使用其他的编码。

<globalization requestEncoding="gb2312" responseEncoding="gb2312" />

创建订单

创建订单时有2种方式,一种是传统的创建订单的Form表单或者Url,另一种是创建订单的支付二维码。

1、传统的创建订单的Form表单或者Url

下面先演示如何使用创建传统的Form表单或者Url支付订单。首先你需要新建一个名为Payment的Web窗体,并在Payment.aspx页面仅保留如下代码:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Payment.aspx.cs" Inherits="Demo.Payment" %>

这样的目的是因为实现了IPaymentForm接口的支付网关在创建订单时会生成并输出完整的Form表单,如果当前页面包含其他内容可能会造成无法提交订单。

下面的代码将演示如何使用支付宝、易宝来创建订单。

private void CreateAlipayOrder()
{
    PaymentSetting paymentSetting = new PaymentSetting(GatewayType.Alipay);
    paymentSetting.SetGatewayParameterValue("seller_email", "[email protected]");
    paymentSetting.Merchant.UserName = "000000000000000";
    paymentSetting.Merchant.Key = "000000000000000000000000000000000000000000";
    paymentSetting.Merchant.NotifyUrl = new Uri("http://yourwebsite.com/Notify.aspx");
    paymentSetting.Order.Amount = 0.01;
    paymentSetting.Order.Id = "35";
    paymentSetting.Order.Subject = "测测看支付宝";

    paymentSetting.Payment();
}



private void CreateYeepayOrder()
{
    PaymentSetting paymentSetting = new PaymentSetting(GatewayType.Yeepay);
    paymentSetting.Merchant.UserName = "000000000000000";
    paymentSetting.Merchant.Key = "000000000000000000000000000000000000000000";
    paymentSetting.Merchant.NotifyUrl = new Uri("http://yourwebsite.com/Notify.aspx");
    paymentSetting.Order.Amount = 0.01;
    paymentSetting.Order.Id = "24";
    paymentSetting.Order.Subject = "测试易宝";

    paymentSetting.Payment();
}

在上面的代码我们使用了支付宝、易宝的支付网关来创建订单,在创建订单时需要设置商户、订单、接收网关支付通知的Url这些必须填写的数据。在使用支付宝时,需要注意这里需要再设置卖家支付宝账号的邮箱,这些额外数据使用SetGatewayParameterValue方法来设置。

在完成必须的设置后,使用Payment方法将会在当前页面输出提交订单的Form或者Url,然后会将用户定向到相应的支付网站。

2、支付二维码

接下来是创建支付二维码,下面的代码是创建微信支付的支付二维码。代码跟创建传统的生成Form表单或者Url订单的代码一致,唯一的区别是Payment方法会在当前页面输出支付二维码的图片,而不再是Form表单或者Url。

private void CreateWeChatPayOrder()
{
    PaymentSetting paymentSetting = new PaymentSetting(GatewayType.WeChatPay);
    paymentSetting.SetGatewayParameterValue("appid", "wx000000000000000");
    paymentSetting.Merchant.UserName = "000000000000000";
    paymentSetting.Merchant.Key = "000000000000000000000000000000000000000000";
    paymentSetting.Merchant.NotifyUrl = new Uri("http://yourwebsite.com/Notify.aspx");
    paymentSetting.Order.Amount = 0.01;
    paymentSetting.Order.Id = "31";
    paymentSetting.Order.Subject = "测测看微信";

    paymentSetting.Payment();
}

在使用微信支付时,需要注意这里还需要再设置额外的appid参数,通过SetGatewayParameterValue方法来添加。


接收支付网关的支付通知

首先你新建之前创建订单中用来接收支付网关通知的名为ServerNotify的Web窗体,并在ServerNotify.aspx页面仅保留如下代码:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ServerNotify.aspx.cs" Inherits="Demo.ServerNotify" %>

这样做的原因是因为接收支付网关通知的页面可能需要输出一些字符表示已接收到支付网关的通知,如果有其他页面内容会造成干扰。

在这个页面将接收并处理多个不同的网关返回的支付通知,代码如下:

protected void Page_Load(object sender, EventArgs e)
{
    Merchant alipayMerchant = new Merchant();
    alipayMerchant.GatewayType = GatewayType.Alipay;
    alipayMerchant.UserName = "0000000000";
    alipayMerchant.Key = "00000000000000000000000000";

    Merchant yeepayMerchant = new Merchant();
    yeepayMerchant.GatewayType = GatewayType.Yeepay;
    yeepayMerchant.UserName = "1000000000000";
    yeepayMerchant.Key = "00000000000000000000000000000000000000000000";

    List<Merchant> merchantList = new List<Merchant>();
    merchantList.Add(alipayMerchant);
    merchantList.Add(yeepayMerchant);

    PaymentNotify notify = new PaymentNotify(merchantList);
    notify.PaymentSucceed += new PaymentSucceedEventHandler(notify_PaymentSucceed);
    notify.PaymentFailed += new PaymentFailedEventHandler(notify_PaymentFailed);
    notify.UnknownGateway += new UnknownGatewayEventHandler(notify_UnknownGateway);

    notify.Received();
}


private void notify_PaymentSucceed(object sender, PaymentSucceedEventArgs e)
{
    // 支付成功时的处理代码
    if (e.PaymentNotifyMethod == PaymentNotifyMethod.AutoReturn)
    {
        // 用户通过浏览器自动返回时充值成功提示
    }
}


private void notify_PaymentFailed(object sender, PaymentFailedEventArgs e)
{
    // 支付失败时的处理代码
}


private void notify_UnknownGateway(object sender, UnknownGatewayEventArgs e)
{
    // 无法识别支付网关时的处理代码
}

首先创建支付网关的商户数据,然后将他们添加到集合。在创建PaymentNotify对象时将商户数据的集合传入构造函数中。接着PaymentNotify在支付成功、失败、无法识别支付网关的事件上注册回调方法,最后使用Received方法来接收支付网关返回的支付通知,它将完成支付通知的处理并引发相应的事件。

在事件的回调方法中你可以通过e.PaymentNotifyMethod属性来获得支付通知是用户通过浏览器自动返回还是由网关服务器发送。如果是用户通过浏览器自动返回这时你可以在页面提示充值以便让用户获得更好的体验。

访问支付通知的原始数据

当你希望访问支付成功、失败、无法识别支付网关的事件数据中未提供的其他支付通知数据时,你可以通过e.GatewayParameterData属性来获得,e.GatewayParameterData属性保存了支付网关返回的所有数据。使用e.GetGatewayParameterValue帮助方法可以更方便的访问支付网关返回的数据,例如在支付宝的支付通知中使用e.GetGatewayParameterValue("buyer_email")方法可以获得买家的支付宝帐号,在微信的支付通知中使用 e.GetGatewayParameterValue("is_subscribe")方法可以知道用户是否关注公众账号。


查询订单

查询订单有2种不同的方式

1、 有的支付网关是立即获得订单的查询结果。

通过向支付网关查询页面发送需要查询的订单数据后,查询页面将输出查询结果。使用这种查询方式的支付网关都实现了IQueryNow接口。

实现了IQueryNow接口的网关,将使用如下方式查询订单的状态

private void QueryYeepayOrder()
{
    PaymentSetting querySetting= new PaymentSetting(GatewayType.Yeepay);
    querySetting.Merchant.UserName = "000000000000000";
    querySetting.Merchant.Key = "0000000000000000000000000000000000000000";

    // 查询时需要设置订单的Id与金额,在查询结果中将会核对订单的Id与金额,如果不相符会返回查询失败。
    querySetting.Order.Id = "1564515";
    querySetting.Order.Amount = 0.01;

    if (paymentSetting.CanQueryNow && paymentSetting.QueryNow())
    {
        // 订单已支付
    }
}

private void QueryWeChatPayOrder()
{
    PaymentSetting querySetting = new PaymentSetting(GatewayType.WeChatPay);
    querySetting.SetGatewayParameterValue("appid", "wx000000000000000");
    querySetting.Merchant.UserName = "000000000000000";
    querySetting.Merchant.Key = "0000000000000000000000000000000000000000";

    // 查询时需要设置订单的Id与金额,在查询结果中将会核对订单的Id与金额,如果不相符会返回查询失败。
    querySetting.Order.Id = "20";
    querySetting.Order.Amount = 0.01;

    if (querySetting.CanQueryNow && querySetting.QueryNow())
    {
        // 订单已支付
    }
}

使用CanQueryNow属性可以查询到当前的支付网关是否实现了IQueryNow接口,是否可以立即获得查询订单结果,如果可以再使用QueryNow方法来获得查询结果,因为并不是所有支付网关都实现了查询功能或者这种查询方式。这里需要注意查询时需要设置订单的Id与金额,在查询结果中将会核对订单的Id与金额,如果不相符会返回查询失败。在使用微信支付时,需要注意这里还需要再设置appid,通过SetGatewayParameterValue方法来添加。

2、 查询订单跟提交订单后接收处理支付网关付款通知的方式一样。

提交查询以后,网关服务器给指定页面发送支付通知,然后你使用处理网关服务器返回付款通知一样的方法来处理订单的查询。

下面的代码演示了提交一个查询

private void QueryNotifyOrder()
{
    PaymentSetting querySetting= new PaymentSetting(GatewayType.None);
    querySetting.Merchant.UserName = "10000000000";
    querySetting.Merchant.Key = "0000000000000000000000000000000000000000";
    querySetting.Merchant.NotifyUrl = new Uri("http://yourwebsite.com/Payment/PaymentNotify.aspx");
    querySetting.Order.OrderId = "1564515";

    if (paymentSetting.CanQueryNotify)
    {
        paymentSetting.QueryNotify();
    }
}

通过CanQueryNotify属性可以知道当前支付网关是否支持这种查询方式,如果支持再使用QueryNotify方法查询。支持查询订单的网关都实现了IQueryForm或者IQueryUrl接口。目前没有实现支持这种查询方式的支付网关,之前使用这种查询方式的网银在线已经删除掉了。


设置额外的数据

一些支付网关可能在生成支付订单或查询时需要一些额外的数据,这些数据通过PaymentSetting.SetGatewayParameterValue方法来设置。

例如支付宝在创建订单时需要设置seller_email,也就是是卖家支付宝账号的邮箱。

PaymentSetting paymentSetting = new PaymentSetting(GatewayType.Alipay);
paymentSetting.SetGatewayParameterValue("seller_email", "[email protected]");

订单Id的建议

不同支付网关对订单Id有不同的限制。它可能被要求的只能是数字、数字英文跟一些指定字符组成,或者有长度限制,详细的说明请阅读相关支付网关的问题。

但共同点就是他们都可以使用数字作为订单Id,如果你需要同时使用多个支付网关,就应该考虑只使用数字作为订单Id。

Clone this wiki locally