微信 支付寶支付 友盟登入分享 統計
一、專案結構與前言
首先看下整體框架
如果我們專案中已經匯入了友盟的SDK,那麼我們就不必在匯入微信 支付寶官方的SDK。
在使用友盟SDK時我們會遇到各種各樣的問題,報錯,例如:#import <UMSocialCore/UMSocialCore.h> not found #import <AlipaySDK/AlipaySDK.h> not found這一類報錯的話,一般都是我們的地址不對,只需要在TARGETS-Build Settings - Header Search Paths裡面修改找不到的類的地址就好。
在我們對接微信支付的時候解析XMl檔案時報錯ARC 檔案提前 釋放時 我們需要在Buils Phases - Compile Sources 裡面的集體的某個控制器或者類的後面新增-fno-objc-arc欄位。
支付寶支付存在APP支付和網頁支付,微信支付只有App支付,
進行支付功能的整合 我們需要在專案中配置它的一些引數。
我們分享的View可以新增到任何位置,並不侷限與下方。
分享的話有微信好友 朋友圈 QQ 空間 微博的分享,為了防止蘋果稽核被拒,友盟已經為我們做好了顯示我們手機安裝的可分享的第三方。
#pragma mark - 判斷平臺是否安裝 - (BOOL)gz_UMSocialIsInstall:(UMSocialPlatformType)platformType { return [GZUMSocialData isInstall:platformType]; }
友盟分享也為我們提供了多種分享模式,純文字 ,帶圖片文 ,純圖片 ,一般的分享是這種,title、content、縮圖、URL , 文字 + 圖片【暫時只對新浪分享有效】 ,音樂 ,視訊 ,gif 動圖等等,完全可以滿足我們的需求。
支付方面的問題絕大多數出現在回撥函式這塊,我們只要按照每個平臺的官方文件進行書寫,一般不會出什麼大的問題。
二、準備工作
1、整合微信支付首先需要註冊(https://open.weixin.qq.com )註冊完成後我們選擇移動應用,建立移動應用,資訊自己填寫, 最後我們需要申請支付功能,這個是需要交money的(300/年)成功後我們需要有一個商戶帳號與之對接,最後就是協議簽署,這樣微信支付大功告成。
2、支付寶支付需要使用者進螞蟻金服官網註冊帳號,來獲取支付功能,同樣它和微信一樣每年300元的費用。
三、程式設計與實現
首先我們介紹我微信支付,微信公眾平臺有多種支付方式,我們選擇的是App支付,整合微信支付按照微信文件進行下載SDK,
適用於商戶在移動端APP中整合微信支付功能。
商戶APP呼叫微信提供的SDK呼叫微信支付模組,商戶APP會跳轉到微信中完成支付,支付完後跳回到商戶APP內,最後展示支付結果。
步驟1:使用者進入商戶APP,選擇商品下單、確認購買,進入支付環節。商戶服務後臺生成支付訂單,簽名後將資料傳輸到APP端。以微信提供的DEMO為例。
步驟2:使用者點選後發起支付操作,進入到微信介面,調起微信支付,出現確認支付介面。
步驟3:使用者確認收款方和金額,點選立即支付後出現輸入密碼介面,可選擇零錢或銀行卡支付。
現在的微信支付SDK應該是在Xcode6的基礎上,
1、專案設定APPID
商戶在微信開放平臺申請開發APP應用後,微信開放平臺會生成APP的唯一標識APPID。在Xcode中開啟專案,設定專案屬性中的URL Schemes為您的APPID。
我們需要在info-URL Types 中填寫商戶自己的AppID
要想能i進行支付,我們還需要微信註冊我們的APPID
//微信支付
[WXApi registerApp:GZWX_APP_KEY];
3、調起支付
商戶伺服器生成支付訂單,先呼叫【統一下單API】生成預付單,獲取到prepay_id後將引數再次簽名傳輸給APP發起支付。以下是調起微信支付的關鍵程式碼:
PayReq *request = [[[PayReq alloc] init] autorelease];
request.partnerId = @"10000100";
request.prepayId= @"1101000000140415649af9fc314aa427";
request.package = @"Sign=WXPay";
request.nonceStr= @"a462b76e7436e98e0ed6e13c64b4fd1c";
request.timeStamp= @"1397527777";
request.sign= @"582282D72DD2B03AD892830965F428CB16E7A256";
[WXApi sendReq:request];
我們需要注意的是,微信支付它的單位是以分來計算的,所以我們整合時,注意下這塊!
- ( NSMutableDictionary *)sendPay_OrderName:(NSString *)ProductName PayPrice:(NSString *)PriductPrice;{
//訂單標題,展示給使用者
NSString *order_name = ProductName;
//訂單金額,單位(分)
// NSString *order_price = PriductPrice ;
NSString *order_price = [NSString stringWithFormat:@"%d",[PriductPrice intValue]];//1分錢測試
對於這塊,因為ARC的緣故我們需要在Build Phases - Compile Sources中新增 -fno-objc-arc
調起微信支付
-(void)ByWeiXinBuy{
[self weXinAplyPayOrderName:@"剛子支付Demo" PayPrice:@"1"];
}
#pragma mark--微信支付
-(void)weXinAplyPayOrderName:(NSString *)OrderName PayPrice:(NSString *)PayPrice{
if (![WXApi isWXAppInstalled]) {
[self.view gz_showAlertView:@"溫馨提示" message:@"未檢測到客戶端,請安裝"];
}else{
//建立支付簽名物件
payRequsestHandler *req = [payRequsestHandler alloc];
//初始化支付簽名物件
[req init:APP_ID mch_id:MCH_ID];
//設定金鑰
[req setKey:PARTNER_ID];
//獲取到實際調起微信支付的引數後,在app端調起支付
NSMutableDictionary *dict = [req sendPay_OrderName:OrderName PayPrice:PayPrice];
if(dict == nil){
//錯誤提示
NSString *debug = [req getDebugifo];
[self.view gz_showAlertView:@"提示資訊" message:debug];
}else{
[self sendRepweixin:dict];//提交支付
}
}
}
-(void)sendRepweixin:(NSDictionary *)dict{
NSMutableString *stamp = [dict objectForKey:@"timestamp"];
//調起微信支付
PayReq* req = [[PayReq alloc] init];
req.openID = [dict objectForKey:@"appid"];
req.partnerId = [dict objectForKey:@"partnerid"];
req.prepayId = [dict objectForKey:@"prepayid"];
req.nonceStr = [dict objectForKey:@"noncestr"];
req.timeStamp = stamp.intValue;
req.package = [dict objectForKey:@"package"];
req.sign = [dict objectForKey:@"sign"];
[WXApi sendReq:req];
}
2、支付寶支付
首先在螞蟻金服建立帳號申請分享 支付功能 (300RMB)
整合支付寶支付,將在官網下載的SDK匯入到專案中
在Build Phases選項卡的Link Binary With Libraries中,增加以下依賴:
其中,需要注意的是:
-
如果是Xcode 7.0之後的版本,需要新增libc++.tbd、libz.tbd;
-
如果是Xcode 7.0之前的版本,需要新增libc++.dylib、libz.dylib
-(void)buyproduct{
//四美坊app商戶ID 使用者ID 私鑰
NSString *pid = @"2088421263479877";
NSString *appID = @"2016092201949956";
NSString *privateKey = @"MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALhNuoy6DrIF27wxQXT1JarZIhCleLbGZIKi/xLGb0KMP6m9xP17GJ0asqhDqIPQOos2vmwmeA8ast2gQQWzbtaKMyqsrxQgrlTvYomwo3579JwOS29wgpjAWn2YQ9t3YGlECpFtoX3KtyJ7JPhtTcfJqPpHiNFjujmPCU83s9qJAgMBAAECgYAw4y1gttm/Dx7CRK6AP6bGMuJ+V+Y1VVrD7EiMymYo2NrqQ5RFSKm2wqYxTAEfNdTRqKvKNEoUd5iKgT++K2JywugECubbv/2hSzUqsr1VhQ/buzIwSTTPFJHrG2WSL+c8hqgsxk3Fn79vKarRnPdYj7r+7xZ43uwfxx/mzaXnoQJBANtyF6P8vjJLazCwrX+bg7CS447c/38Nsai6CTOr4GyvEzd+sIUkFahTGzk83qBdU4ksMGfGrv7Bwvk5X2c4AcMCQQDXAQ9067qOtGsWXiDgNqDe2+CgNotXwhBOKGlbv3t9xYi89K2u9hqIz3yUWBbbxOaolCJvpFREJV4mmtXQiEHDAkEAr1tijMZg7ivaQhRM8FXDTAx1DyqGeG7m8t+GjuXf9rmIb6YrRJlrPRD8Bicf96HcKRdIrwTTvfvz49f25rKYpQJBAK+OvRlCdlWZ+isMdxm9YYQ30+XeQ89Htdqr4sO4ydQ73Fg2Di/j4my9x0K13wxabeFO/ANfEjOGs6cgHOCmsdMCQQCNyYE6MloO1xaHkFIRuzMjUJB94Wkaip/DzZE5a/vIsm6mk6JcaPDCGAm2yf2xd6f/1y0WViaSLv6jLcdwZCZ8";
//pid和appID獲取失敗,提示
if ([pid length] == 0 ||
[appID length] == 0 ||
[privateKey length] == 0)
{
[self.view gz_showAlertView:@"提示" message:@"缺少pid或者appID或者私鑰。"];
return ;
}
/*
*生成訂單資訊及簽名
*/
Order* order = [Order new];
//將商品資訊賦予AlixPayOrder的成員變liang
// NOTE: app_id設定
order.app_id = appID;
order.notify_url = @"http://www.88meichou.com/api/alipay/alipay.php";
order.biz_content.seller_id = pid ;
// NOTE: 支付介面名稱
order.method = @"alipay.trade.app.pay";
// NOTE: 引數編碼格式
order.charset = @"utf-8";
// NOTE: 當前時間點
NSDateFormatter* formatter = [NSDateFormatter new];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
order.timestamp = [formatter stringFromDate:[NSDate date]];
// NOTE: 支付版本
order.version = @"1.0";
// NOTE: sign_type設定
order.sign_type = @"RSA";
// NOTE: 商品資料
order.biz_content = [BizContent new];
order.biz_content.body = @"剛子支付Demo";
order.biz_content.subject = [NSString stringWithFormat:@"購買%@美豆",@"1"];
order.biz_content.out_trade_no = order_sn ;
// order.biz_content.out_trade_no = [self generateTradeNO]; //訂單ID(由商家自行制定)
order.biz_content.timeout_express = @"30m"; //超時時間設定
// order.biz_content.total_amount = [NSString stringWithFormat:@"%.2f",0.01];
order.biz_content.total_amount = [NSString stringWithFormat:@"%@", @"0.1"]; //商品價格
//將商品資訊拼接成字串
NSString *orderInfo = [order orderInfoEncoded:NO];
NSString *orderInfoEncoded = [order orderInfoEncoded:YES];
// NSLog(@"orderSpec = %@",orderInfo);
// NOTE: 獲取私鑰並將商戶資訊簽名,外部商戶的加簽過程請務必放在服務端,防止公私鑰資料洩露;
// 需要遵循RSA簽名規範,並將簽名字串base64編碼和UrlEncode
id<DataSigner> signer = CreateRSADataSigner(privateKey);
NSString *signedString = [signer signString:orderInfo];
// NOTE: 如果加簽成功,則繼續執行支付
if (signedString != nil) {
//應用註冊scheme,在AliSDKDemo-Info.plist定義URL types
NSString *appScheme = @"ap2016092201949956";
// NOTE: 將簽名成功字串格式化為訂單字串,請嚴格按照該格式
NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@",
orderInfoEncoded, signedString];
// NSLog(@"~~~~~~~~~~~!!~~~~~~~~~~%@",orderString);簽名
// NOTE: 呼叫支付結果開始支付
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
// NSLog(@"reslut = %@",resultDic);
NSString * str = resultDic[@"memo"];
// NSLog(@"~~~~~!!~~%@",str);
NSString *result = resultDic[@"resultStatus"];
if ([result isEqualToString:@"9000"]) {
#pragma 回掉函式
}
}];
}
}
回撥的話我們在最後給出 ,因為他們可以寫在一個方法中
3、友盟分享 統計
註冊友盟帳號,
UMConfigInstance.appKey = GZUmengAppkey ;
UMConfigInstance.channelId = @"App Store" ;
[MobClick startWithConfigure:UMConfigInstance];開啟統計
NSString *appVersion = [NSString stringWithFormat:@"2、獲取APP的版本號:%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]];
[MobClick setAppVersion:appVersion];
//對統計資料進行加密
[MobClick setEncryptEnabled:YES];
分享的話 我做了一個分類,這樣顯得AppDelegate裡面不是那麼的亂。
#pragma mark - ***** 友盟分享
- (void)addShareOpt
{
GZShareManage *manager = [GZShareManage shareManage];
[manager gz_setupShareConfig];
#import <Foundation/Foundation.h>
#import <UMSocialCore/UMSocialCore.h>
#import <MessageUI/MessageUI.h>
@protocol GZShareManageDelegate <NSObject>
/*! 返回使用者資訊 */
- (void)getUserData:(NSDictionary *)backUserData;
@end
typedef NS_ENUM(NSUInteger, GZUM_SHARE_TYPE)
{
/*! 純文字 */
GZUM_SHARE_TYPE_TEXT = 1,
/*! 純圖片:本地圖片 */
GZUM_SHARE_TYPE_IMAGE,
/*! 純圖片:網路圖片 URL */
GZUM_SHARE_TYPE_IMAGE_URL,
/*! 網頁:一般的分享是這種,title、content、縮圖、URL */
GZUM_SHARE_TYPE_WEB_LINK,
/*! 文字 + 圖片 【暫時只對新浪分享有效】 */
GZUM_SHARE_TYPE_TEXT_IMAGE,
/*! 音樂 */
GZUM_SHARE_TYPE_MUSIC_LINK,
/*! 視訊 */
GZUM_SHARE_TYPE_VIDEO_LINK,
/*! gif 動圖【注:目前只有微信支援動圖分享,其他平臺均不支援】*/
GZUM_SHARE_TYPE_GIF,
/*! 檔案【注:目前只有微信支援動圖分享,其他平臺均不支援】 */
GZUM_SHARE_TYPE_FILE
};
/*! 登入後返回的資料回撥 */
typedef void (^GZUMLoginCallback)(UMSocialUserInfoResponse *response);
@interface GZShareManage : NSObject
/*! 登入後返回的資料回撥 */
@property (nonatomic, copy) GZUMLoginCallback loginCallback;
/*! 分享標題 */
@property (nonatomic, strong) NSString *shareTitle;
/*! 分享摘要 */
@property (nonatomic, strong) NSString *shareText;
/*! 分享大圖【本地 imageName】】 */
@property (nonatomic, strong) NSString *shareBigImage;
/*! 分享 URL 圖片 */
@property (nonatomic, strong) NSString *shareImageUrl;
/*! 分享網頁 */
@property (nonatomic, strong) NSString *shareWebpageUrl;
/*! 分享音樂 URL【必傳】 */
@property (nonatomic, strong) NSString *shareMusicUrl;
/*! 分享音樂 DataUrl */
@property (nonatomic, strong) NSString *shareMusicDataUrl;
/*! 分享視訊 URL */
@property (nonatomic, strong) NSString *shareVideoUrl;
/*! 分享 gif 動圖路徑 */
@property (nonatomic, strong) NSString *shareGifFilePath;
/*! 分享檔案路徑 */
@property (nonatomic, strong) NSString *shareFileFilePath;
/*! 分享檔案字尾型別 */
@property (nonatomic, strong) NSString *shareFileFileExtension;
/*! 授權回撥 */
@property (nonatomic, strong) void (^authOpFinish)();
@property (nonatomic, strong) id<GZShareManageDelegate> delegate;
/*! 圖片陣列 */
@property (nonatomic, strong) NSArray *shareImageArray;
/*! 分享的名字陣列(要和圖片名字一一對應哦!) */
@property (nonatomic, strong) NSArray *shareNameArray;
//// 友盟分享SDK的各種key設定【pod下來後只需呼叫下即可】
//@property (nonatomic, strong) NSString *GZShareUmengAppkey;
//@property (nonatomic, strong) NSString *GZShareSinaAppKey;
//@property (nonatomic, strong) NSString *GZShareWX_APP_KEY;
//@property (nonatomic, strong) NSString *GZShareWX_APP_SECRET;
//@property (nonatomic, strong) NSString *GZSharekQQKey;
//@property (nonatomic, strong) NSString *GZSharekQQAppID;
+ (GZShareManage *)shareManage;
/*!
* 友盟分享設定
*/
- (void)gz_setupShareConfig;
/*!
* 判斷平臺是否安裝
*
* @param platformType 平臺型別 @see UMSocialPlatformType
*
* @return YES 代表安裝,NO 代表未安裝
* @note 在判斷QQ空間的App的時候,QQApi判斷會出問題
*/
- (BOOL)gz_UMSocialIsInstall:(UMSocialPlatformType)platformType;
#pragma mark - 友盟分享 version 2.1
/*! 微信分享 */
#pragma mark 微信分享 version 2.1
- (void)gz_wechatShareWithShareType:(GZUM_SHARE_TYPE)shareType
viewController:(UIViewController *)viewController;
#pragma mark 微信朋友圈分享 version 2.1
- (void)gz_wechatTimeLineShareWithShareType:(GZUM_SHARE_TYPE)shareType
viewController:(UIViewController *)viewController;
#pragma mark 新浪微博分享 version 2.1
- (void)gz_sinaShareWithShareType:(GZUM_SHARE_TYPE)shareType
viewController:(UIViewController *)viewController;
#pragma mark qq分享 version 2.1
- (void)gz_qqShareWithShareType:(GZUM_SHARE_TYPE)shareType
viewController:(UIViewController *)viewController;
#pragma mark Qzone分享 version 2.1
- (void)gz_qZoneShareWithShareType:(GZUM_SHARE_TYPE)shareType
viewController:(UIViewController *)viewController;
#pragma mark - 友盟分享
/*!
* 剛子友盟分享列表 version 2.1
*
* @param shareType 分享型別,具體看列舉
* @param viewController viewController
*/
- (void)gz_shareListWithShareType:(GZUM_SHARE_TYPE)shareType
viewController:(UIViewController *)viewController;
#pragma mark - 友盟登入
#pragma mark 微信登入 version 2.1
- (void)gz_wechatLoginWithViewController:(UIViewController *)viewController
isGetAuthWithUserInfo:(BOOL)isGetAuthWithUserInfo
loginCallback:(GZUMLoginCallback)loginCallback;
#pragma mark QQ登入 version 2.1
- (void)gz_qqLoginWithViewController:(UIViewController *)viewController
isGetAuthWithUserInfo:(BOOL)isGetAuthWithUserInfo
loginCallback:(GZUMLoginCallback)loginCallback;
#pragma mark QQZone登入 version 2.1
- (void)gz_qZoneLoginWithViewController:(UIViewController *)viewController
isGetAuthWithUserInfo:(BOOL)isGetAuthWithUserInfo
loginCallback:(GZUMLoginCallback)loginCallback;
#pragma mark 微博登入 version 2.1
- (void)gz_sinaLoginWithViewController:(UIViewController *)viewController
isGetAuthWithUserInfo:(BOOL)isGetAuthWithUserInfo
loginCallback:(GZUMLoginCallback)loginCallback;
#pragma mark - 友盟登入列表 version 2.1
/*!
* 友盟登入列表 version 2.1
*
* @param viewController viewController description
* @param isGetAuthWithUserInfo
YES:授權並獲取使用者資訊(獲取uid、access token及使用者名稱等)
NO:只需獲取第三方平臺token和uid,不獲取使用者名稱等使用者資訊,可以呼叫以下介面
* @param loginCallback 登入後返回的資料回撥
*/
- (void)gz_loginListWithViewController:(UIViewController *)viewController
isGetAuthWithUserInfo:(BOOL)isGetAuthWithUserInfo
loginCallback:(GZUMLoginCallback)loginCallback;
#pragma mark - 清除授權
- (void)gz_cancelAuthWithPlatformType:(UMSocialPlatformType)platformType;
@end
}
以下為微信支付寶支付成功回撥 友盟分享回撥!
// NOTE: 9.0以後使用新API介面
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options
{
if ([url.host isEqualToString:@"safepay"]) {
// 支付跳轉支付寶錢包進行支付,處理支付結果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
// NSLog(@"result = %@",resultDic);
[[NSNotificationCenter defaultCenter]postNotificationName:@"alipayResult" object:[resultDic objectForKey:@"resultStatus"]];
}];
return YES ;
}else if ([url.host isEqualToString:@"pay"]) {
return [WXApi handleOpenURL:url delegate:self];
}else{
return [[UMSocialManager defaultManager] handleOpenURL:url];
}
}
/**
這裡處理新浪微博SSO授權之後跳轉回來,和微信分享完成之後跳轉回來
*/
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
if ([url.host isEqualToString:@"safepay"]) {
// 支付跳轉支付寶錢包進行支付,處理支付結果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
// NSLog(@"result = %@",resultDic);
[[NSNotificationCenter defaultCenter]postNotificationName:@"alipayResult" object:[resultDic objectForKey:@"resultStatus"]];
}];
return YES ;
}else if ([url.host isEqualToString:@"pay"]) {
return [WXApi handleOpenURL:url delegate:self];
}else{
return [[UMSocialManager defaultManager] handleOpenURL:url];
}
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
if ([url.host isEqualToString:@"safepay"]) {
// 支付跳轉支付寶錢包進行支付,處理支付結果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
[[NSNotificationCenter defaultCenter]postNotificationName:@"alipayResult" object:[resultDic objectForKey:@"resultStatus"]];
}];
return YES ;
}else if ([url.host isEqualToString:@"pay"]) {
return [WXApi handleOpenURL:url delegate:self];
}else{
return [[UMSocialManager defaultManager] handleOpenURL:url];
}
}
//微信支付結果
- (void) onResp:(BaseResp*)resp
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"weixinPay" object:resp];
四、執行效果
效果圖如下:
由於專案過大不能整體上傳的平臺 ,所以一些包檔案請移步百度網盤進行下載,地址上面有!