iOS WeChat-Zahlungszugriff und Tool-Kapselung

WeChat Pay wurde in einem gerade abgeschlossenen Projekt verwendet. Vom Zugriff auf WeChat Pay bis zur Tool-Kapselung werde ich es in diesem Artikel für die zukünftige Verwendung zusammenfassen.

1. Beginnen Sie mit den Vorbereitungen für den Zugriff auf die WeChat-Zahlung

Greifen Sie auf „process.png“ zu

Zunächst müssen Sie ein Konto auf der offenen WeChat-Plattform registrieren. Ich möchte hier eine Beschwerde einreichen. Ich kenne den Konto- und Passwortüberprüfungsmechanismus dieser WeChat-Plattform nicht. Wenn ich mein vorheriges Passwort vergesse und mich erneut anmelde , alle Methoden zum Abrufen des Passworts funktionieren nicht. Mir bleibt nichts anderes übrig, als eines zu registrieren. Gmail.com, nach erfolgreicher Anmeldung sehen Sie die folgende Oberfläche.
1.png

Klicken Sie oben rechts auf „Mobile Anwendung erstellen“ und geben Sie Schritt für Schritt die erforderlichen Informationen ein. Ich werde hier nicht auf unnötige Details eingehen.
Es ist zu beachten, dass die hier eingegebene Bundle-ID
in einer Eins-zu-Eins-Entsprechung mit dem Projekt stehen muss.
BoundleId
Warten Sie als Nächstes etwa eine Woche. Nachdem die WeChat-Überprüfung bestanden wurde, können Sie das WeChat Payment SDK in das integrieren Projekt. Weitere Informationen finden Sie in der offiziellen Dokumentation zur
Pod-Integrationsmethode

pod 'WechatOpenSDK'

Wählen Sie in Xcode Ihre Projekteinstellungen aus, wählen Sie die Spalte „TARGETS“ aus und fügen Sie „URL-Schema“ als Ihre registrierte Anwendungs-ID im „URL-Typ“ der Registerkartenleiste „Info“ hinzu (wie in der Abbildung unten gezeigt).
URL-Schema

Nach Abschluss können Sie die App-ID (den eindeutigen Identifikationscode, der von der offenen WeChat-Plattform für die Anwendung generiert wird), die Händler-ID und den Händler-Geheimschlüssel erhalten. Für die App-Seite wird nur die App-ID verwendet. Die Händler-ID erhält man am besten über die Schnittstelle vom Server. Der Merchant SecretKey wird für die Signatur verwendet und kann im Allgemeinen nur vom Server verwendet werden.

2. Zahlungsvorgang

Zahlungsvorgang.png

Dieses Flussdiagramm mag auf den ersten Blick kompliziert erscheinen. Um unseren Vergleichsprozess zusammenzufassen:
1. Der App-Client sendet eine Zahlungsanforderung an den Server
. 2. Nach Erhalt der Client-Anfrage ruft der Server die einheitliche Bestell-API auf, um das WeChat-Backend zu erhalten Prepaid-Bestellinformationen
3. Der Server generiert signierte Client-Zahlungsinformationen für die App.
4. Der App-Client-Benutzer bestätigt die Zahlung und die App weckt den WeChat-Client, um die Zahlung durchzuführen.
5. Nachdem die App das Zahlungsergebnis erhalten hat, fragt sie das ab Server für das Endergebnis und die Show

Arbeiten Sie auf der App-Seite:
  • Greifen Sie auf das WeChat Payment SDK zu
  • Zahlungsanforderung an den Server senden
  • Die Zahlungsinformationen aktivieren die WeChat-App und führen dann die Zahlung durch.
  • Bestätigen Sie nach Erhalt des WeChat-Zahlungsrückrufs das Zahlungsergebnis dem Server
  • Zeigen Sie die Ergebnisseite basierend auf den Abfrageergebnissen an, um den Benutzer über die Zahlungsergebnisse zu informieren
Serverseitige Arbeit:
  • Nachdem Sie die Zahlungsanforderung vom App-Client erhalten haben, fordern Sie im WeChat-Backend einen Vorauszahlungsauftrag an
  • Der Server signiert die Informationen und gibt sie an den App-Client zurück
  • Erhalten Sie die vom WeChat-Hintergrund zurückgegebenen Zahlungsergebnisse und verwenden Sie diese zur Abfrage auf der App-Seite

Vom Server zurückgegebene Feldbeschreibung:

  • appId: appid zurückgegeben
  • partnerId: 父级id
  • prepayId: Zahlungs-ID
  • Pakete: Paketname (der Standardwert für WeChat ist „Sign=WXPay“)
  • nonceStr: generierte Zufallszeichenfolge
  • timesTamp: Zeitstempel
  • Zeichen: Unterschrift
    Feld Beschreibung

3. Verwendung unter iOS

Importieren Sie in AppDelegate.m, die WeChat SDK-Header-DateiWXApi.h

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[WXApi registerApp:@"注册获得的appid"];//注册appid
    return YES;
}

 //支持所有iOS系统回调
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
//    [self handleOpenURL:url];
    BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url sourceApplication:sourceApplication annotation:annotation];
    if (!result) {
        // 其他如支付等SDK的回调
        [self handleOpenURL:url];
    }
    return YES;
}
- (void)handleOpenURL:(NSURL*)url {
    if ([url.host isEqualToString:@"pay"]) { // -- 微信支付
        [WXApi handleOpenURL:url delegate:[WXPayService sharedInstance]];
    }
}

Was hier ist, WXPayServiceist eine Klasse, die ich separat geschrieben habe und WXApiManagerDelegatedem Protokoll folgt.

WXPayService.h
#import <Foundation/Foundation.h>
#import "WXApi.h"
@interface WXPayService : NSObject <WXApiDelegate>
///单例来接收微信请求的回调
+ (instancetype)sharedInstance;
// -- 根据接口返回的预支付信息,构造支付请求
+ (PayReq *)getPayRequest:(NSDictionary *)prepayData;

///处理非支付请求的回调
- (void)onRespCallBack:(void(^)(BaseResp * resp))callback;
///从服务器端获取到微信返回的支付请求用到的参数来发起支付请求
- (void)startPayWithReq:(PayReq *)req callback:(void(^)(BaseResp * resp))callback; 
@end
WXPayService.m

#import "WXPayService.h"
@interface WXPayService ()
@property (nonatomic,copy) void(^RespCallBack)(BaseResp *);
@end
static WXPayService *sharedInstance;

@implementation WXPayService
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [super allocWithZone:zone];
    });
    return sharedInstance;
}
///单例来接收微信请求的回调
+ (instancetype)sharedInstance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

// -- 根据接口返回的预支付信息,构造支付请求
+ (PayReq *)getPayRequest:(NSDictionary *)prepayData {
    if (prepayData) {
//  此处Tools是自己的另一个工具类,用来判断字典的
        PayReq *req = [[PayReq alloc] init];
        if ([Tools dicContain:prepayData withKey:@"partnerid"]) {
            req.partnerId = prepayData[@"partnerid"];
        }
        if ([Tools dicContain:prepayData withKey:@"prepayid"]) {
            req.prepayId = prepayData[@"prepayid"];
        }
        if ([Tools dicContain:prepayData withKey:@"noncestr"]) {
            req.nonceStr = prepayData[@"noncestr"];
        }
        if ([Tools dicContain:prepayData withKey:@"timestamp"]) {
            req.timeStamp = [prepayData[@"timestamp"] intValue];
        }

        req.package =@"Sign=WXPay";
        req.sign =  @"null";
        //日志输出
        NSLog(@"appid=%@/npartid=%@/nprepayid=%@/nnoncestr=%@/ntimestamp=%ld/npackage=%@/nsign=%@",[prepayData objectForKey:@"appid"],req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign);
        return req;
    }
    return nil;
}

///处理非支付请求的回调
- (void)onRespCallBack:(void(^)(BaseResp * resp))callback {
    self.RespCallBack = callback;
}
///从服务器端获取到微信返回的支付请求用到的参数来发起支付请求
- (void)startPayWithReq:(PayReq *)req callback:(void(^)(BaseResp * resp))callback {
    NSAssert(req !=nil , @"未成功创建微信支付请求");
    self.RespCallBack = callback;
    if ([WXApi isWXAppInstalled]) { // -- 判断是否安装微信应用
        //发起微信支付,设置参数
        [WXApi sendReq:req];
    }else {
        self.RespCallBack(nil);
    }
}

#pragma mark WXApiDelegate
- (void)onResp:(BaseResp *)resp {
    if ([resp isKindOfClass:[PayResp class]]) { // -- 判断是否为支付的回调
        self.RespCallBack(resp);
    }
}
@end

Importieren Sie die zu bezahlende Werkzeugklasse in den ViewControllerWXPayService
pay.png

4. Aufmerksamkeitspunkte und Probleme

wichtiger Punkt:

  • Legen Sie das Schema fest, andernfalls kann die Anwendung nicht zum WeChat-Client springen
  • Die Schlüsselwerte beim Signieren der Zahlung sind alle in Kleinbuchstaben geschrieben.
  • Wenn die Zahlung zeigt, dass die Signaturüberprüfung fehlgeschlagen ist
    , können Sie versuchen, die Pakete auf den Standardwert (Sign=WXPay) zu setzen.

Frage:

Wenn die Systemversion größer oder gleich iOS9 ist, können Sie nach dem Starten des WeChat-Clients direkt auf die Schaltfläche auf der linken Seite der Statusleiste klicken, um zurückzukehren. Zu diesem Zeitpunkt wird die Rückrufmethode nicht verwendet.

Lösung:
Rufen Sie in der applicationWillEnterForeground-Methode von AppDelegate.m die Schnittstelle für die Abfrage des Zahlungsergebnisses auf und aktualisieren Sie dann die Seite. Sie müssen eine Bool-Variable als Flag festlegen, da sie sonst nicht den Geschäftsanforderungen entspricht, wenn Sie sie jedes Mal abfragen, wenn die Anwendung in den Vordergrund tritt.

Nachdem Sie die WeChat-Zahlungsseite aufgerufen haben, wechseln Sie zu Ihrer eigenen Anwendung, ohne einen Vorgang auszuführen, verlassen Sie die aktuelle Zahlungsseite, rufen Sie dann den WeChat-Client auf und klicken Sie auf „Bezahlen“ oder „Abbrechen“. Zu diesem Zeitpunkt stürzt Ihre Anwendung ab und wird beendet.

Grund: Nach dem Verlassen der Seite wurde die Seite aus dem Stapel entfernt und zerstört, aber die Proxy-Methode wird während des wx-Rückrufs weiterhin aufgerufen und ein Platzhalterzeiger wird angezeigt.
Lösung: viewWillDisappearZur Seitenmethode hinzufügen

[WXPayService sharedManager].delegate = nil;

5. Schlussfolgerung

Für WeChat-Zahlungssignaturen wird empfohlen, mit dem Server eine sekundäre Signatur auszuhandeln, um die Zahlungssicherheit zu gewährleisten.
ps: Wenn etwas nicht stimmt, kritisieren und korrigieren Sie mich bitte. Bitte überprüfen Sie auch meinen persönlichen Blog .

おすすめ

転載: blog.csdn.net/chuzhaohzi/article/details/79804096