APP payment: IOS Mobile Phone + java background edition, appios
APP payment (IOS mobile client + java background)0.Introduction Preview
For scenarios where you need to access native payment on IOS Mobile Phones, call to make payment.
1. Data Preparation
1.1 account registration
1.2 developer Authentication
Log on to the account center and perform developer qualification authentication.
1.3 register an application
After the authentication is complete, go to the management center and create a new mobile application. Enter the application information. For more information, see the document. After the creation is complete, click View to apply for payment. Everything is ready!
2.
Java Background Development
Add dependency
[Html] view plaincopy
Print?
Org. xmlpull
Xmlpull
1.1.3.1
Net. sf. json-lib
Json-lib
2.3
Jdk15
Com. thoughtworks. xstream
Xstream
1.4.5
Com. ning
Async-http-client
1.8.13
Generate unified order
[Java] view plaincopy
Print?
@ RequestMapping (value = "/pay/wxpay/params", produces = "application/json; charset = UTF-8 ")
@ ResponseBody
PublicStringsignprams (HttpServletRequestrequest ){
Stringres = "{code: 404 }";
Try {
// Recharge Amount
Stringaccount = request. getParameter ("account ");
// User ID
Stringsid = request. getParameter ("sid ");
Stringsubject = "Order title ";
Stringbody = "order description ";
Intacc = (int) (Double. valueOf (account) * 100 );
Stringappid = "Your APPID ";
Stringout_trade_no = "generate your order number ";
// Generate order data
SortedMappayMap = genOrderData (request, subject, body, acc, appid, out_trade_no );
SavePayLog (out_trade_no, account, sid, body, payMap. get ("paySign"), nid, 2 );
// 4. return data
Res = buildPayRes (payMap, out_trade_no );
} Catch (effectione ){
E. printStackTrace ();
Res = & quot; {code: 500} & quot }";
}
Returnres;
}
PrivateSortedMapgenOrderData (HttpServletRequestrequest, Stringsubject, Stringbody,
Intacc, Stringappid, Stringout_trade_no)
ThrowsIOException, ExecutionException, InterruptedException, XmlPullParserException {
SortedMapparaMap = newTreeMap ();
ParaMap. put ("appid", appid );
ParaMap. put ("attach", subject );
ParaMap. put ("body", body );
ParaMap. put ("mch_id", "Your merchant id, go to the merchant platform to view ");
ParaMap. put ("nonce_str", create_nonce_str ());
ParaMap. put ("yy_url", "https://pay.xxxxx.com/pay/wxpay/notify.htm"); // This path is the server call payment result notification path
ParaMap. put ("out_trade_no", out_trade_no );
ParaMap. put ("spbill_create_ip", request. getRemoteAddr ());
ParaMap. put ("total_fee", acc + "");
ParaMap. put ("trade_type", "APP ");
Stringsign = createSign (paraMap );
ParaMap. put ("sign", sign );
// Unified order https://api.mch.weixin.qq.com/pay/unifiedorder
Stringurl = "https://api.mch.weixin.qq.com/pay/unifiedorder ";
Stringxml = getRequestXml (paraMap );
StringxmlStr = HttpKit. post (url, xml );
// Prepaid item id
Stringprepay_id = "";
If (xmlStr. indexOf ("SUCCESS ")! =-1 ){
Mapmap = WXRequestUtil. doXMLParse (xmlStr );
Prepay_id = (String) map. get ("prepay_id ");
}
SortedMappayMap = newTreeMap ();
PayMap. put ("appid", appid );
PayMap. put ("partnerid", "Your merchant id, go to the merchant platform to view ");
PayMap. put ("prepayid", prepay_id );
PayMap. put ("package", "Sign = WXPay ");
PayMap. put ("noncestr", create_nonce_str ());
PayMap. put ("timestamp", WXRequestUtil. create_timestamp ());
StringpaySign = createSign (payMap );
PayMap. put ("paySign", paySign );
ReturnpayMap;
}
// Request xml assembly
PublicstaticStringgetRequestXml (SortedMapparameters ){
Stringsign = "";
StringBuffersb = newStringBuffer ();
Sb. append ("
Setes = parameters. entrySet ();
Iteratorit = es. iterator ();
While (it. hasNext ()){
Map. Entryentry = (Map. Entry) it. next ();
Stringkey = (String) entry. getKey ();
Stringvalue = (String) entry. getValue ();
// If ("attach". inclusignorecase (key) | "body". inclusignorecase (key) | "sign". inclusignorecase (key )){
// Sb. append ("<" + key + ">" + value + "");
//}
If ("sign". inclusignorecase (key )){
Sign = "<" + key + ">" + value + "";
} Else {
Sb. append ("<" + key + ">" + value + "");
}
}
Sb. append (sign );
Sb. append ("");
Returnsb. toString ();
}
// Generate a signature
PublicStringcreateSign (SortedMapparameters ){
StringBuffersb = newStringBuffer ();
Setes = parameters. entrySet ();
Iteratorit = es. iterator ();
While (it. hasNext ()){
Map. Entryentry = (Map. Entry) it. next ();
Stringk = (String) entry. getKey ();
Objectv = entry. getValue ();
If (null! = V &&! "". Equals (v)
&&! "Sign". equals (k )&&! "Key". equals (k )){
Sb. append (k + "=" + v + "&");
}
}
Sb. append ("key =" + WXConfig. APP_PERTNER_KEY );
System. out. println (sb. toString ());
Stringsign = MD5Utils. MD5Encode (sb. toString (), "UTF-8"). toUpperCase ();
Returnsign;
}
PublicStringcreate_nonce_str (){
Stringchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";
Stringres = "";
For (inti = 0; I <32; I ++ ){
Randomrd = newRandom ();
Res + = chars. charAt (rd. nextInt (chars. length ()-1 ));
}
Returnres;
}
3. IOS client development
Import Development Kit
Add URL Types
Register an application in AppDelegate. m.
[Objc] view plaincopy
Print?
# Import "AppDelegate. h"
# Import "XSTabBarViewController. h"
# Import
# Import "WXApi. h"
@ InterfaceAppDelegate ()
@ End
@ ImplementationAppDelegate
-(BOOL) application :( UIApplication *) applicationdidfinishlaunchingwitexceptions :( NSDictionary *) launchOptions {
// Overridepointforcustomizationafterapplicationlaunch.
// [NSThreadsleepForTimeInterval: 2.0];
// Enter the master controller
Self. window = [[uiappswalloc] init];
Self. window. frame = [UIScreenmainScreen]. bounds;
Self. window. rootViewController = [[XSTabBarViewControlleralloc] init];
[Self. windowmakeKeyAndVisible];
// Register an application.
[WXApiregisterApp: @ "wxfb96c2a9b531be26"];
ReturnYES;
}
-(Void) onResp :( BaseResp *) resp
{
// NSLog (@ "---- onResp % @", resp );
/*
ErrCodeERR_ OK = 0 (user consent)
ERR_AUTH_DENIED =-4 (the user rejects authorization)
ERR_USER_CANCEL =-2 (User canceled)
The code that the user exchanges for access_token is valid only when ErrCode is 0.
The identifier used by a state third-party program to identify the uniqueness of the request. It is passed in when a third-party program calls sendReq and is returned by the terminal. The length of the state string cannot exceed 1 K.
Current lang client language
Country user's current country information
*/
If ([respisKindOfClass: [SendAuthRespclass]) // determines whether the request is an authorization request. Otherwise, the request conflicts with the payment and other functions.
{
SendAuthResp * aresp = (SendAuthResp *) resp;
If (aresp. errCode = 0)
{
// NSLog (@ "code % @", aresp. code );
[[Nsnotifcencenterdefacenter] postNotificationName: @ "wechatDidLoginNotification" object: selfuserInfo :@{@ "code": aresp. code}];
}
} Else {// callback of the payment request
// Return the payment result. The actual payment result must be queried on the server.
NSString * strMsg = [NSStringstringWithFormat: @ "Payment result"];
NSString * respcode = @ "0 ";
Switch (resp. errCode ){
CaseWXSuccess:
StrMsg = @ "Payment result: successful! ";
// NSLog (@ "Payment successful-PaySuccess, retcode = % d", resp. errCode );
Respcode = @ "1 ";
Break;
Default:
StrMsg = [NSStringstringWithFormat: @ "Payment result: failed! Retcode = % d, retstr = % @ ", resp. errCode, resp. errStr];
// NSLog (@ "error, retcode = % d, retstr = % @", resp. errCode, resp. errStr );
Respcode = @ "0 ";
Break;
}
[[Nsnotifcencenterdefacenter] postNotificationName: @ "wechatDidPayNotification" object: selfuserInfo :@{@ "respcode": respcode}];
}
}
// The handling method before iOS9.0 is not guaranteed to be correct. If any error occurs, correct it.
-(BOOL) application :( UIApplication *) applicationopenURL :( NSURL *) urlsourceApplication :( NSString *) sourceApplicationannotation :( id) annotation
{
NSLog (@ "before iOS9.0 ");
Return [selfapplicationOpenURL: url];
}
-(BOOL) application :( UIApplication *) appopenURL :( NSURL *) urloptions :( NSDictionary *) options {
NSLog (@ "after iOS9.0 ");
Return [selfapplicationOpenURL: url];
}
-(BOOL) applicationOpenURL :( NSURL *) url
{
If ([[urlabsoluteString] rangeOfString: @ "wxfb96c2a9b531be26: // pay"]. location = 0 ){
Return [WXApihandleOpenURL: urldelegate: self];
}
If ([url. hostisEqualToString: @ "safepay"])
{
[[Alipaysdkdefaservice Service] processOrderWithPaymentResult: urlstandbyCallback: nil];
ReturnYES;
}
ReturnYES;
}
}
Receive payment notification in the Controller to be paid
[Objc] view plaincopy
Print?
-(Void) viewDidLoad {
[SuperviewDidLoad];
// Receive payment notification
[[Nsnotificationcenterdefacenter] addObserver: selfselector: @ selector (wechatDidPayNotification :) name: @ "wechatDidPayNotification" object: nil];
}
Obtain unified orders from the server and pull up for payment
[Objc] view plaincopy
Print?
-(Void) weixinPay
{
NSString * userUrlStr = [NSStringstringWithFormat: @ "% @? Sid =%@ & account =%@ & desc =%@ ", WX_PREPAY_URL, self. student. sid, self. payJinE, self. student. nid];
NSURL * url = [NSURLURLWithString: userUrlStr];
// NSLog (@ "userUrlStr = % @", userUrlStr );
NSURLRequest * request = [NSURLRequestrequestWithURL: url];
AFHTTPRequestOperation * operation = [[AFHTTPRequestOperationalloc] initWithRequest: request];
[MBProgressHUDshowMessage: @ "Jump in progress, please wait"];
[OperationsetCompletionBlockWithSuccess: ^ (AFHTTPRequestOperation * operation, NSDictionary * responseObject ){
[MBProgressHUDhideHUD];
// NSLog (@ "paid response =%@", operation. responseString );
NSData * JSONData = [operation. responseStringdataUsingEncoding: NSUTF8StringEncoding];
NSDictionary * userDict = [NSJSONSerializationJSONObjectWithData: JSONDataoptions: NSJSONReadingMutableLeaveserror: nil];
// Call the payment method
PayReq * request = [[PayReqalloc] init];
/** The id of the merchant applied for from caifu Tong */
Request. partnerId = [userDictobjectForKey: @ "partnerid"];
/** Pre-payment order */
Request. prepayId = [userDictobjectForKey: @ "prepayid"];
/** The data and signature entered by the merchant according to the caifu Tong document */
Request. package = [userDictobjectForKey: @ "package"];
/** Random string, anti-resend */
Request. nonceStr = [userDictobjectForKey: @ "noncestr"];
/** Timestamp, anti-resend */
Request. timeStamp = [[userDictobjectForKey: @ "timestamp"] intValue];
/** The seller signs the data based on the open platform Documentation */
Request. sign = [userDictobjectForKey: @ "sign"];
Self. sign = request. sign;
Self. ordnum = [userDictobjectForKey: @ "ordnum"];
[WXApisendReq: request];
} Failure: ^ (AFHTTPRequestOperation * operation, NSError * error ){
[MBProgressHUDhideHUD];
NSLog (@ "error! % @ ", Error );
}];
NSOperationQueue * queue = [[NSOperationQueuealloc] init];
[QueueaddOperation: operation];
}
// Payment result
-(Void) wechatDidPayNotification :( NSNotification *) notification
{
// NSLog (@ "wechatDidPayNotification ");
NSDictionary * nameDictionary = [icationicationuserinfo];
NSString * respcode = [nameDictionaryobjectForKey: @ "respcode"];
If ([respcodeisinclutostring: @ "1"]) {
// The payment is successful and the user information is updated
[SelfpayDidFinish];
} Else {
// Payment failed,
[SelfsetupAlertControllerWithTitle: @ "Payment result" messge: @ "this payment has not been completed. You can try again later! "Confirm: @" OK "];
}
}