代码之家  ›  专栏  ›  技术社区  ›  LizG

当从应用程序向firebase函数向PayPal发送数据时,不会创建通知电子邮件

  •  0
  • LizG  · 技术社区  · 6 年前

    我在firebase中有一个应用程序,我试图将参数发送到firebase函数中的函数,该函数将发送到PayPal,但它不起作用。

    func payoutRequest() {
    
        print("payoutRequest")
    
        let driver_uid = self.uid!
        let email = txtPayoutEmail.text!
        let url = "https://us-central1-ryyde-sj.cloudfunctions.net/payout"
    
        let paypal_token = "mytoken"
    
        let params : Parameters = [
            "uid": driver_uid,
            "email": email
        ]
    
        let headers : HTTPHeaders = [
            "Content-Type": "application/json",
            "Accept": "application/json",
            "Authorization": "\(paypal_token)",
            "cache-control": "no-cache"
        ]
    
        Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON { (response) in
    
    
            print("Request: \(String(describing: response.request))")   // original url request
            print("Response: \(String(describing: response.response))") // http url response
            print("Result: \(response.result)") // response serialization result
    
    
            switch response.result {
            case .success(let value):
                print(value)
    
                if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                    print("Data: \(utf8Text)") 
                }
    
            case .failure(let error):
                print("Error while querying database: \(String(describing: error))")
                return
            }
        }
    }
    

    payoutRequest
    Request: Optional(https://us-central1-ryyde-sj.cloudfunctions.net/payout)
    Response: Optional(<NSHTTPURLResponse: 0x6000010109a0> { URL: https://us-central1-ryyde-sj.cloudfunctions.net/payout } { Status Code: 200, Headers {
        "Content-Length" =     (
            0
        );
        "Content-Type" =     (
            "text/html"
        );
        Date =     (
            "Sun, 13 Jan 2019 23:37:26 GMT"
        );
        Server =     (
            "Google Frontend"
        );
        "alt-svc" =     (
            "quic=\":443\"; ma=2592000; v=\"44,43,39,35\""
        );
        "function-execution-id" =     (
            1fcniah306ur
        );
        "x-cloud-trace-context" =     (
            "b4cb4d1470906270abb0b04efa99ea37;o=1"
        );
        "x-powered-by" =     (
            Express
        );
    } })
    Result: FAILURE
    Error while querying database: responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength)
    

    'use strict';
    const functions = require('firebase-functions');
    const paypal = require('paypal-rest-sdk');
    const admin = require('firebase-admin');
    admin.initializeApp(functions.config().firebase);
    
    paypal.configure({
        mode: 'sandbox',
        client_id: functions.config().paypal.client_id,
        client_secret: functions.config().paypal.client_secret
    })
    
    exports.newRequest = functions.database.ref('/history/{pushId}').onCreate((snapshot, context) => {
        var requestSnapshot = snapshot.val();
        var price  = snapshot.child('price').val();
        var pushId = context.params.pushId;
    
        return snapshot.ref.parent.child(pushId).child('price').set(price);
     });
    
    
    function getPayoutsPending(uid) {
        return admin.database().ref('Users/Drivers/' + uid + '/history').once('value').then((snap) => {
            if(snap === null){
                throw new Error("profile doesn't exist");
            }
            var array = [];
            if(snap.hasChildren()){
                snap.forEach(element => {
                    if (element.val() === true) {
                        array.push(element.key);
                    }
                });
            }
            return array;
        }).catch((error) => {
            return console.error(error);
        });
    }
    
    function getPayoutsAmount(array) {
        return admin.database().ref('history').once('value').then((snap) => {
            var value = 0.0;
            if(snap.hasChildren()){
                snap.forEach(element => {
                    if(array.indexOf(element.key) > -1) {
                            if(element.child('price').val() !== null){
                                value += element.child('price').val();
                            }
                    }
                });
                return value;
            }
            return value;
        }).catch((error) => {
            return console.error(error);
        });
    }
    
    function updatePaymentsPending(uid, paymentId) {
        return admin.database().ref('Users/Drivers/' + uid + '/history').once('value').then((snap) => {
            if(snap === null){
                throw new Error("profile doesn't exist");
            }
    
            if(snap.hasChildren()){
                snap.forEach(element => {
                    if(element.val() === true) {
                        admin.database().ref('Users/Drivers/' + uid + '/history/' + element.key).set( {
                            timestamp: admin.database.ServerValue.TIMESTAMP,
                            paymentId: paymentId
                        });
                        admin.database().ref('history/' + element.key + '/driverPaidOut').set(true);
                    }
                });
            }
            return null;
        }).catch((error) => {
            return console.error(error);
        });
    }
    
    exports.payout = functions.https.onRequest((request, response) => {
        return getPayoutsPending(request.body.uid)
            .then(array => getPayoutsAmount(array))
            .then(value => {
                var valueTrunc = parseFloat(Math.round((value * 0.75) * 100) / 100).toFixed(2);
                const sender_batch_id = Math.random().toString(36).substring(9);
                const sync_mode = 'false';
                const payReq = JSON.stringify({
                    sender_batch_header: {
                        sender_batch_id: sender_batch_id,
                        email_subject: "You have a payout!"
                    },
                    items: [
                        {
                            recipient_type: "EMAIL",
                            amount: {
                                value: valueTrunc,
                                currency: "CAD"
                            },
                            note: "Thank you.",
                            sender_item_id: "Payout",
                            receiver: request.body.email
                        }
                    ]
                });
    
                return paypal.payout.create(payReq, sync_mode, (error, payout) => {
                    if (error) {
                        console.warn(error.response);
                        response.status('500').end();
                        throw error;
                    }
                    console.info("uid: " + request.body.uid + " email: " + request.body.email) 
                    console.info("payout created");
                    console.info(payout);
                    return updatePaymentsPending(request.body.uid, sender_batch_id)
                });
            }).then(() => {
                response.status('200').end();
                return null;
            }).catch(error => {
                console.error(error);
            });
    });
    

    编辑1

    根据我研究过的其他请求,我稍微更改了payoutRequest()。它将显示一个.200状态码,但仍然无法在PayPal上获得支付通知:

    func payoutRequest() {
    
        print("payoutRequest")
    
        //Progress View
        self.progress.progress = value
        self.perform(#selector(updateProgressView), with: nil, afterDelay: 1.0)
    
        let email = txtPayoutEmail.text!
    
        let url = "https://us-central1-ryyde-sj.cloudfunctions.net/payout"
    
        let params : [String: Any] = [
            "uid": self.uid!,
            "email": email
        ]
    
        let headers : HTTPHeaders = [
            "Content-Type": "application/json",
            "Authorization": "my token",
            "Cache-Control": "no-cache"
        ]
    
        let myData = try? JSONSerialization.data(withJSONObject: params, options: [])
        print("data: \(String(describing: myData))")
    
       Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers)
            .validate(statusCode: 200..<300)
            .validate(contentType: ["application/json"])
            .responseData(completionHandler: { (response) in
    
            //print("Request: \(String(describing: response.request))")   // original url request
            //print("Response: \(String(describing: response.response))") // http url response
            print("Result: \(response.result)")                         // response serialization result
    
            switch response.result {
            case .success:
                print("Validation Successful")
                let parsedObject = try! JSONSerialization.jsonObject(with: myData!, options: .allowFragments)
                print("parsed: \(parsedObject)")
    
            case .failure(let error):
                print(error)
            }
        })
    }
    

    我从指纹中得到的反应是:

    payoutRequest
    data: Optional(58 bytes)
    Result: SUCCESS
    Validation Successful
    parsed: {
        email = "me@me.com";
        uid = o2a30PjFufSBYtSIUR5UWFpwPcr1;
    }
    

    从firebase函数可以看到,它被接受,参数被接收。

    firebase-function log

    API Call

    但是,如果我 https://developer.paypal.com/developer/notifications/

    我试过很多不同的发帖请求,但我试过的都没有成功。我在网上试过辅导。我对这一点还不太了解,不明白它为什么不起作用。

    0 回复  |  直到 6 年前