Case 4 '支付寶支付
成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供番禺網(wǎng)站建設(shè)、番禺做網(wǎng)站、番禺網(wǎng)站設(shè)計(jì)、番禺網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、番禺企業(yè)網(wǎng)站模板建站服務(wù),十載番禺做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
Dim cmd, subject, body, order_no, prices, rurl, types, number, transport, ordinary_fee, express_fee, readonlytrue, buyer_msg, buyer, buyer_name, buyer_address, buyer_zipcode, buyer_tel, buyer_mobile, partner As String
Dim t1, t2, t3, t4, t5 As String
Dim AlipayObj, itemUrl As String
t1 = ":" '支付接口
t2 = ConfigurationSettings.AppSettings("adminaliPay") '商戶支付寶賬戶(改成你自己的)
t3 = "m7yeav29bcdz14szvi2rbfcixywob59y" '安全校驗(yàn)碼
cmd = "0001" '命令碼
subject = "訂單號(hào):" NoID '商品名稱
body = Convert.ToString(ViewState("CourseName")) '商品描述
order_no = NoID '商戶訂單號(hào)
prices = Convert.ToString(ViewState("NowPrice")) '商品單價(jià)
rurl = Request.Url.ToString() '商品展示網(wǎng)址
types = "1" '支付類型 1:商品購買,2:服務(wù)購買,3:網(wǎng)絡(luò)拍賣,4:捐贈(zèng)
number = "1" '購買數(shù)量
transport = "3" '發(fā)貨方式 1:平郵,2:快遞,3:虛擬物品
ordinary_fee = "0" '平郵運(yùn)費(fèi)
express_fee = "0" '快遞運(yùn)費(fèi)
readonlytrue = "true" '交易信息是否只讀,true或false,默認(rèn)值為false
buyer_msg = "" '買家給賣家的留言:string(200)
'buyer = Convert.ToString(ViewState("txtIDEmail")) '買家Email
buyer_name = Convert.ToString(ViewState("txtIDName")) ",Email:" Convert.ToString(ViewState("txtIDEmail")) '買家姓名,買家Email
buyer_address = Convert.ToString(ViewState("txtIDaddress")) '買家地址
buyer_zipcode = Convert.ToString(ViewState("txtIDPost")) '買家郵編
buyer_tel = Convert.ToString(ViewState("txtIDtelephone")) '買家電話號(hào)碼
buyer_mobile = Convert.ToString(ViewState("txtIDTel")) '買家手機(jī)號(hào)碼
partner = "" '合作伙伴ID(保留字段)
itemUrl = creatAlipayItemURL(t1, t2, t3, t4, t5, cmd, subject, body, order_no, prices, rurl, types, number, transport, ordinary_fee, express_fee, readonlytrue, buyer_msg, buyer, buyer_name, buyer_address, buyer_zipcode, buyer_tel, buyer_mobile, partner)
itemUrl = "script language=javascript" vbCrLf "!--" vbCrLf "document.forms[0].submit();" vbCrLf "http://--" vbCrLf "/script"
Response.Write(itemUrl)
End Select
在VB.NET的類里,實(shí)現(xiàn)一個(gè)接口的語句是:
implements接口名稱
例如,下面定義一個(gè)車(總稱)的接口,這里的車是各種車的總稱:
Public Interface ICar
Property color() As String
Property speed() As Long
Sub PrintInfo()
End Interface
然后在不同類型的“車”類里實(shí)現(xiàn)它:
Public Class A_Car
Implements ICar
Dim m_color As String, m_speed As Long
Public Property color() As String Implements ICar.color
Get
Return m_color
End Get
Set(ByVal Value As String)
m_color = Value
End Set
End Property
Protected Overrides Sub Finalize()
MsgBox(I was deconstructed!)
End Sub
Public Sub New()
m_color = Red
m_speed = 210
MsgBox(I was constructed!)
End Sub
Public Property speed() As Long Implements ICar.speed
Get
Return m_speed
End Get
Set(ByVal Value As Long)
m_speed = speed
End Set
End Property
Public Sub PrintInfo() Implements ICar.PrintInfo
MsgBox(Color: m_color vbNewLine Speed: m_speed, MsgBoxStyle.Information)
End Sub
End Class
在 Form 的 Load 事件中編寫:
Dim myCar As New A_Car
myCar.PrintInfo()
運(yùn)行之后就創(chuàng)建了一個(gè) A_Car 類的實(shí)例 myCar,然后出現(xiàn)兩個(gè)對(duì)話框,分別說明實(shí)例已經(jīng)創(chuàng)建和汽車的信息。當(dāng)窗體卸載時(shí),這個(gè)類的實(shí)例 myCar 將自動(dòng)銷毀,這時(shí)將出現(xiàn)一個(gè)“I was deconstructed!”的對(duì)話框。
聲明一個(gè)接口時(shí),需要考慮以下幾點(diǎn):
1.接口主體只限于對(duì)方法,索引器以及屬性的聲明;
2.接口成員是隱式公開的,如果對(duì)其顯式指定訪問級(jí)別,就會(huì)出現(xiàn)編譯器錯(cuò)誤;
3.接口中不能包含字段,構(gòu)造函數(shù)和常量等;
4.在接口中不能實(shí)現(xiàn)任何方法,屬性或者索引器;
5.在指定方法時(shí),只需要給出返回類型,名稱和參數(shù)列表,然后分號(hào)結(jié)束。
面向?qū)ο蟮慕涌?/p>
在C++中,一個(gè)類被允許繼承多個(gè)類。但是在Java以后的語言不被允許。
這樣,如果想繼承多個(gè)類時(shí)便非常困難。所以開發(fā)方想出了新辦法:接口。
一個(gè)接口內(nèi),允許包含變量、常量等一個(gè)類所包含的基本內(nèi)容。但是,接口中的函數(shù)不允許設(shè)定代碼,也就意味著不能把程序入口放到接口里。由上可以理解到,接口是專門被繼承的。接口存在的意義也是被繼承。和C++里的抽象類里的純虛函數(shù)是相同的。不能被實(shí)例化。
定義接口的關(guān)鍵字是interface,例如:
publicinterfaceMyInterface{
public void add(int x,int y);
public void volume(int x,int y,int z);
}
繼承接口的關(guān)鍵字是implements,相當(dāng)于繼承類的extends。
需要注意的是,當(dāng)繼承一個(gè)接口時(shí),接口里的所有函數(shù)必須全部被覆蓋。例如:
class Demo implements MyInterface{
public void add(int x,int y){
System.out.println( +(x+y));
}
public void volume(int x,int y,int z){
System.out.println( +(x*y*z));
}
public static void main(String args[]){
Demo d=new Demo();
d.add(10,20);
d.volume(10,10,10);
}
}
輸出結(jié)果:
30
1000
當(dāng)想繼承多個(gè)類時(shí),開發(fā)程序不允許,報(bào)錯(cuò)。這樣就要用到接口。因?yàn)榻涌谠试S多重繼承(,),而類不允許。所以就要用到接口。
接入支付寶支付SDK
可以說支付寶支付接入是所有SDK最好接入的,沒有之一。
客戶端不用簽名,也不用管包名,也不用管簽名文件,就接口返回訂單,把訂單交給支付寶SDK調(diào)用就行,成功或者失敗都在當(dāng)前界面返回給你。你再去通知接口。
支付流程圖
官方文檔地址
!支付寶支付官方文檔地址
按照文檔說明接入SDK和相關(guān)配置,在這就不重復(fù)了
客戶端支付關(guān)鍵代碼===》支付接口的調(diào)用(調(diào)起支付彈框)
記住支付接口的調(diào)用必須在獨(dú)立的非ui線程中執(zhí)行,即需新開線程里面調(diào)用??梢韵牍俜絛emo一樣用new Thread方式。
下面我給出用Observable方式示例代碼
在PayUtils中
/**
* desc:支付寶支付
* Created by congge on 2018/8/27 17:20
* @param orderInfo 接口返回的訂單
**/
public static void aliPay(final Activity activity, final String orderInfo, final OrderListener orderListener) {
Observable.just(orderInfo)
.map(new Function () {
@Override
public String apply(String orderInfo) throws Exception {
//用戶在商戶app內(nèi)部點(diǎn)擊付款,是否需要一個(gè)loading做為在錢包喚起之前的過渡,這個(gè)值設(shè)置為true
return new PayTask(activity).pay(orderInfo, true);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer () {
@Override
public void accept(String payResult) throws Exception {
orderListener.onPayResult(payResult);
}
});
}
支付結(jié)果返回處理
返回例子:
resultStatus={9000};memo={};result={{"alipay_trade_app_pay_response":{"code":"10000","msg":"Success","app_id":"2016091300503896","auth_app_id":"2016091300503896","charset":"utf-8","timestamp":"2018-08-28 17:51:11","out_trade_no":"nVElbd74TW6WnEyxQwvX8A","total_amount":"0.01","trade_no":"2018082821001004680500208879","seller_id":"2088102175487650"},"sign":"W0Hg9k4GxL8Oaxymvqk2i65WNDQxYp6HGve32ek6VjSRnymmI3GQTjpQVbZuDzvjcwQ/HIkM97PoBGAVlTmi/wiJcqDgSSDzDY7AFnNN0OcK0ehWGwKQINA4IDGh51A7yY/vYKmR0VW+2OwGhlRPPMMZtQOEqh8a9/aIijzT6ZLwy9Hl4ayG/fVKhdC1VdckF6+C25BFNp3fIxarg5tfEunm7N9iWngKCUsnP+IZz05OHdvynimgYPcBnbBERHG97GVqRT/EdBWTQyIDMc0LemScAYxJixTVgXDkRddQjzWZ7HgLdBfjs0nXY24puHudT76ERxVY+8NkoKle/QI+FA==","sign_type":"RSA2"}}
也可以自己打log看看
處理示例代碼:
//支付寶支付
PayUtils.aliPay(this, result.getSignDataStr(), new PayUtils.OrderListener() {
@Override
public void onPayResult(String payResult) {
PayResult pr = new PayResult(payResult);
String rs = pr.getResultStatus();
String r = pr.getResult();
switch (rs) {
case AliPayResultStatus.PAY_SUCCESS:
ToastUtils.show(R.string.pay_success);
//通知接口支付成功
break;
case AliPayResultStatus.PAY_PROCESSING:
case AliPayResultStatus.PAY_UNKNOWN:
ToastUtils.show(R.string.pay_fail);
//支付可能成功,要接口去查詢
break;
default:
ToastUtils.show(R.string.pay_fail);
//通知接口支付失敗,取消訂單
}
}
});
上面方法中:
//通知接口支付成功 //支付可能成功,要接口去查詢 //通知接口支付失敗,取消訂單。根據(jù)你產(chǎn)品需求要不要通知你服務(wù)器做的操作。正常是要的,用來改變訂單狀態(tài)
PayResult.class
public class PayResult {
private String resultStatus;
private String result;
private String memo;
public PayResult(String rawResult) {
if (TextUtils.isEmpty(rawResult))
return;
String[] resultParams = rawResult.split(";");
for (String resultParam : resultParams) {
if (resultParam.startsWith("resultStatus")) {
resultStatus = gatValue(resultParam, "resultStatus");
}
if (resultParam.startsWith("result")) {
result = gatValue(resultParam, "result");
}
if (resultParam.startsWith("memo")) {
memo = gatValue(resultParam, "memo");
}
}
}
@Override
public String toString() {
return "resultStatus={" + resultStatus + "};memo={" + memo
+ "};result={" + result + "}";
}
private String gatValue(String content, String key) {
String prefix = key + "={";
return content.substring(content.indexOf(prefix) + prefix.length(),
content.lastIndexOf("}"));
}
public String outOrder() {
String order = ""out_trade_no"";
if (result.contains(order)) {
String begin = result.substring(result.indexOf(order));
String ss = begin.split(",")[0];
String newS = ss.replace(""", "")
.replace("}", "")
.replace(":", "")
.replace("out_trade_no", "");
try {
return newS;
} catch (Exception e) {
e.printStackTrace();
}
}
return "";
}
/**
* @return the resultStatus
*/
public String getResultStatus() {
return resultStatus;
}
/**
* @return the memo
*/
public String getMemo() {
return memo;
}
/**
* @return the result
*/
public String getResult() {
return result;
}}
最后給下支付返回碼表
AliPayResultStatus.class
public class AliPayResultStatus {
/**
* 訂單支付成功,唯一肯定是支付成功的
*/
public static final String PAY_SUCCESS = "9000";
/**
* 正在處理中,支付結(jié)果未知(有可能已經(jīng)支付成功),請(qǐng)查詢商戶訂單列表中訂單的支付狀態(tài)
*/
public static final String PAY_PROCESSING = "8000";
/**
* 訂單支付失敗
*/
public static final String PAY_FAIL = "4000";
/**
* 重復(fù)請(qǐng)求
*/
public static final String PAY_REPEAT = "5000";
/**
* 用戶中途取消
*/
public static final String PAY_PROCESS_CANCEL = "6001";
/**
* 網(wǎng)絡(luò)連接出錯(cuò)
*/
public static final String PAY_NET_ERROR = "6002";
/**
* 支付結(jié)果未知(有可能已經(jīng)支付成功),請(qǐng)查詢商戶訂單列表中訂單的支付狀態(tài)
*/
public static final String PAY_UNKNOWN = "6004";}
還有一個(gè)直接棄用沙箱調(diào)試模式,否則提示支付失敗也有可能不知道錯(cuò)在那,怕金額大,和接口商量,測(cè)試服務(wù)器就用0.01測(cè)試。