Wechat sharing (payment) and QQ sharing

Premise:

Xcode12.5 + download real machine debugging dmg

Wechat SDK (WechatOpenSDK) 1.8.7.1

QQ Internet SDK (Tencent OpenAPI (LITE)_ 3.5.3.62)

When generating app applications, you need to check Associated Domains, otherwise an error will be reported when compiling later. (I remember xcode10 can be checked locally, but xcode12 does not have this development)

Part1 -- > wechat friend list and circle of friends<--

1) Upload the Apple App site association file on the website. In order to be compatible with the version, it can be in the root directory and subdirectory " Send a copy of "well-know n". The format is probably like this

Suppose the development group id = "AB12345678"; Product bundle id = "com.xxx.app" website= https://123test.com

For simplicity, there is only one app for a site, so fill in * directly for paths. If multiple apps need to be filled in carefully.

{
  "applinks": {
    "apps": [
      
    ],
    "details": [
      {
        "appID": "AB12345678.com.xxx.app",
        "paths": [
        "*"
        ]
      }
    ]
  }
}

2) Apply for wechat mobile app APPID

Fill in the bundle id(com.xxx.app) and the website universal link( https://123test.com ), and App Store id, which needs to be in appstoreconnect.apple.com First create a product (actually fill in some product information), then save it to get an id and apply for a wechat appid(wx12345678).

Download WechatOpenSDK, and then configure info list

LSApplicationQueriesSchemes adds two values

weixin
weixinULAPI

These values are mainly used for jump calls

Associated domains in signing & capabilities

Add applinks: 123test.com (this has no impact on wechat sharing, but it has an impact on qq sharing)

Finally, the code:

This is registered after startup (wechat payment public code)

[WXApi registerApp:@"wx12345678" universalLink:@"https://123test.com"]

Initiate sharing

    WXMediaMessage *message = [WXMediaMessage message];
    message.title = @"Title ";
    message.description = @""Description";

//Remember to compress the picture within 64k (Android seems to be 32k)
    if (image) {
        [message setThumbImage:image];//Share pictures. Use the setThumbImage method of SDK to compress the picture size
    }
    
    // Web page data objects contained in multimedia messages
    WXWebpageObject *webpageObject = [WXWebpageObject object];
    // url address of the web page
    webpageObject.webpageUrl = link;  //link
    message.mediaObject = webpageObject;

    SendMessageToWXReq *sendReq = [[SendMessageToWXReq alloc] init];
    sendReq.bText = NO;
    sendReq.message = message;
    sendReq.scene = flag;  //0 = friends list 1 = circle of friends 2 = favorites 3 =... Look at the record
    
    [WXApi sendReq:sendReq completion:^(BOOL success) {
        //OK
    }];

The callback (return app) is in appdelegate M internal treatment:

//Set Universal Links system callback
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler{

    //NSLog(@"userActivity.webpageURL=%@",userActivity.webpageURL);
    //NSLog(@"restorationHandler=%@",restorationHandler);
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb])
    {
        NSURL *webpageURL = userActivity.webpageURL;   //https://123test.com/wx12345678/
        if (webpageURL) {
            if ([webpageURL.absoluteString rangeOfString:@"wx12345678"].length)
            { // WeChat
				BOOL flag=[WXApi handleOpenUniversalLink:userActivity delegate:(id)self];
				[WXApi handleOpenURL:url delegate:self];  //Compatible with previous versions and can be ignored
                return flag;
            }
        }
    }
    return YES;
}

The above is the code of wechat sharing. Next, let's mention several wechat payment pits.

The premise of wechat payment is that the wechat sharing above has been transferred.

There is not much that can be done on the client. The first step is to initiate an order request, and then the server initiates a payment request to wechat according to the order, returning a string of json strings like this

{"return_code":"SUCCESS","return_msg":"OK","result_code":"SUCCESS","mch_id":"...,"appid":"...","nonce_str":"...","sign":"..".,"prepay_id":"...","trade_type":"APP"}

Then, transfer information to wechat APP through SDK and open wechat. On the basis of sharing success, wechat payment is almost natural. But there are two more pits.

1. "The appid parameter passed in by the merchant is incorrect, please contact the merchant for processing": the first step is to apply for the payment function on the wechat development application account and associate it with the merchant id; The second step is to use the appid of the mobile application for signing on the server, so Android and iOS need to be handled separately. Some people say that the same prompt is given when the order expires within 2 hours. It seems wrong. I tested it with the new version of wechat, which clearly prompts "order timeout expires" and so on.

2. "Signature verification failed": for the first time, we used the appid and AppSecret of the mobile application, which didn't work (even if we changed the sign, it also failed, so we're sure we can't use this AppSecret). Later, we used the unified AppSecret with Android and others, and changed the returned sign value to other values (that is, it can't be the same as the returned string), Then pay successfully...

Part2 -- > QQ and QQ space sharing < --

Apply for APPID on QQ Internet, assuming you get the URL Schema = "QQ12345678xx" Universal Link=“ https://123test.com/qq_conn/1234567899/ ”In fact, APPID = "1234567899" in fact, you only need to fill in "tencent+appid" (Tencent 1234567899) in the URL Types of info. That "QQ12345678xx" is useless at all. It's safe to add it.

Modify the website Apple App site association file

{
  "applinks": {
    "apps": [
      
    ],
    "details": [
      {
        "appID": "AB12345678.com.xxx.app",
        "paths": [
        "*"
        ]
      },
      {
        "appID": "AB12345678.com.xxx.app",
        "paths": [
        "*",
        "/qq_conn/1234567899/*"
        ]
      }
    ]
  }
}

Modify info list:

LSApplicationQueriesSchemes add values

mqq
mqqapi
mqqwpa
mqqbrowser
mqqOpensdkSSoLogin
mqqopensdkapiV2
mqqopensdkapiV3
mqqopensdkapiV4
mqqopensdknopasteboard
wtloginmqq2
mqzone
mqzoneopensdk
mqzoneopensdkapi
mqzoneopensdkapi19
mqzoneopensdkapiV2
mqqapiwallet
mqqopensdkfriend
mqqopensdkdataline
mqqgamebindinggroup
mqqopensdkgrouptribeshare
tencentapi.qq.reqContent
tencentapi.qzone.reqContent

(in the actual debugging of the new version, I only found that mqqapi and mqqopensdknopadeboard were used, and the others were copied from the Internet)

QQ interconnection must use: (xcode12.5) signing & capabilities - > associated domains add an item "applinks: 123test.com ”Generally, the https header should be removed according to the Universal Link filled in when applying for qq interconnection. Note applinks: don't add / / later. If there is an error here, you may be prompted that "the device is not authorized (error code 25105)". Even if everything else is right, you can't find the problem. Take a look at this passage. Error code 25105 appears. There are four places to doubt: 1 Apple App site Association on the website; 2. Fill in applinks; 3.info. LSApplicationQueriesSchemes in the list; 4.info.list URL Types (as mentioned earlier, authorization should have little to do with this, but more to do with that)

The code is also three segment.

1. Registration authorization

[[TencentOAuth alloc] initWithAppId:QQAPPID andUniversalLink:QQULink andDelegate:(id)delegate];  //This return value needs to be saved. You can consider making a global variable

2. Sharing

    QQApiNewsObject *newsObj = [QQApiNewsObject
                                objectWithURL:[NSURL URLWithString:link]
                                title:title
                                description:desc
                                previewImageURL:thumb_url];
    SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:newsObj];
    if (mode == 0)
    {
        QQApiSendResultCode code = [QQApiInterface sendReq:req];
        //NSLog(@"QQ friends list share -% d",code);
        if (code==EQQAPISENDSUCESS) {

        }
    }
    else if (mode == 1)
    {
        QQApiSendResultCode code = [QQApiInterface SendReqToQZone:req];
        //NSLog(@"QQ space sharing -% d",code);
        if (code==EQQAPISENDSUCESS) {

        }
    }

3. Processing responses

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler;
{
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb])
    {
        NSURL *webpageURL = userActivity.webpageURL;
        NSLog(@"webpageURL=%@",webpageURL);
        if (webpageURL) {
           if([webpageURL.scheme isEqualToString:[NSString stringWithFormat:@"tencent%@",QQAPPID]])  //This didn't come in. I wrote it casually
            {
                return [TencentOAuth HandleUniversalLink:webpageURL];
            }
            else if([TencentOAuth CanHandleUniversalLink:webpageURL])  //This judgment doesn't seem to work. I wrote it casually
            {
                return [TencentOAuth HandleUniversalLink:webpageURL];
            }
        }
    }
    return NO;
}

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
	//SDK3.5.1 Click to return to the app, and the url format is "tencent{appid}://response_from_qq?xxxxxx"

    if ([url.scheme isEqualToString:[NSString stringWithFormat:@"tencent%@",QQAPPID]])
    {
        return [QQApiInterface handleOpenURL:url delegate:(id)self];
    }
}


- (void)onReq:(id)req
{
    //else if([[req class] isSubclassOfClass:[QQBaseReq class]])
    //{
    //    //Processing requests from QQ
    //}
}

- (void)onResp:(id)resp
{
    //if([[resp class] isSubclassOfClass:[QQBaseReq class]])
    //{
    //    //Process the response from QQ        
    //}
}

QZone returns directly and automatically after sharing; QQ sharing requires you to choose to click back or stay on QQ.

If you want to know, give up sharing, through

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options

What can be extracted:

tencent{qq-appid}://response_from_qq?error_description=dGhlIHVzZXIgZ2l2ZSB1cCB0aGUgY3VycmVudCBvcGVyYXRpb24=&appsign_bundlenull=2&source=qq&source_scheme=mqqapi&error=-4&version=1

Solve the description base64 to get "the user give up the current operation".

Sharing success is like this:

tencent{qq-appid}://response_from_qq?appsign_bundlenull=2&source=qq&source_scheme=mqqapi&error=0&version=1

If you just share, regardless of the results, you don't have to deal with it in theory

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler;    //QQ Internet sdk3 5.1 didn't come here
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options;  //QQ Internet sdk3 5.1 come here
- (void)onReq:(id)req ;    
 - (void)onResp:(id)resp;

The summary is a little confused and the expression is a little lacking...

Keywords: iOS

Added by eb1024 on Fri, 21 Jan 2022 20:30:06 +0200