Как получить комиссионный сбор за успешную оплату с помощью облачной функции для Firebase? - PullRequest
0 голосов
/ 01 декабря 2018

Я работаю над проектом с угловым 6, элементами Stripe и Google Firebase (с облачными функциями).Все это для меня ново!

За всю свою жизнь я не могу понять, как я могу вернуть «что-то», в котором говорится, что платеж прошел успешно.Документы Stripe API утверждают, что он возвращает вызов ошибки только при наличии «ошибки» ...

Я вижу, что карта успешно заряжается из объекта начисления в Firebase.

Что я могу использовать, чтобы запросить это и вернуть значение «status: paid» моему внешнему интерфейсу ... чтобы я мог использовать * ngIf для отображения сообщения о подтверждении / ошибке?

Я знаю, что яупустить что-то очень простое здесь ...!Я очень ценю любую помощь с этими парнями.

index.js (облачная функция)

const functions = require('firebase-functions');
const admin = require('firebase-admin')

admin.initializeApp(functions.config().firebase);

const stripe = require('stripe') 
(functions.config().stripe.testkey)

exports.stripeCharge = functions.database
.ref('/payments/{paymentId}')
.onWrite((change, context) => {
const payment = change.after.val();

const paymentId = context.params.paymentId;

// checks if payment exists or if it has already been charged
if (!payment || payment.charge) {
  return
}

return admin.database()
  .ref('/users/')
  .once('value')
  .then(snapshot => {
    return snapshot.val()
  })

  .then(customer => {
    const amount = payment.amount;
    const idempotency_key = paymentId; // prevent duplicate charges
    const source = payment.token.id;
    const currency = 'gbp';
    const charge = { amount, currency, source };

    return stripe.charges.create(charge, { idempotency_key });
  })

  .then(charge => {
    admin.database()
      .ref(`/payments/${paymentId}/charge`)
      .set(charge)
      return true;
  })
});

Payment.service.ts

import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';

@Injectable()
export class PaymentService { 

constructor(private db: AngularFireDatabase) {}

// save the token to firebase, triggering the cloud function
processPayment(token: any, amount) {
  const payment = { token, amount }
  return this.db.list('/payments/').push(payment)
  }
}

payment.component.ts(вот мой обработчик onSubmit для проверки)

async onSubmit(form: NgForm) {
//this.paymentProcess = true;
const { token, error } = await stripe.createToken(this.card, {
  name: this.contactName,
  email: this.contactEmail
});

if (error) {  
  console.log('Something is wrong:', error);
} else {
  console.log('Success!', token);
    this.paymentSvc.processPayment(token, this.amount);
  }
  this.card.clear();
}

1 Ответ

0 голосов
/ 01 декабря 2018

Вы должны изменить свой код облачной функции следующим образом, чтобы вернуть обещание, возвращаемое асинхронным методом .set(charge).

exports.stripeCharge = functions.database
.ref('/payments/{paymentId}')
.onWrite((change, context) => {
const payment = change.after.val();

const paymentId = context.params.paymentId;

// checks if payment exists or if it has already been charged
if (!payment || payment.charge) {
  return
}

return admin.database()
  .ref('/users/')
  .once('value')
  .then(snapshot => {
    return snapshot.val()
  })

  .then(customer => {
    const amount = payment.amount;
    const idempotency_key = paymentId; // prevent duplicate charges
    const source = payment.token.id;
    const currency = 'gbp';
    const charge = { amount, currency, source };

    return stripe.charges.create(charge, { idempotency_key });
  })

  .then(charge => {
    return admin.database()  <-- Here return !!!!!!
      .ref(`/payments/${paymentId}/charge`)
      .set(charge);
      //return true;    <-- Here don't return !!!!!!
  })
});

Чтобы "вернуть" статус: оплачено'value to front-end .. ", просто установите listener на путь /payments/${paymentId}/charge, и как только заряд будет иметь правильное значение состояния, обновите ваш front-end.


Наконец, обратите внимание, что с помощью:

  ...
  .then(charge => {
    admin.database()
      .ref(`/payments/${paymentId}/charge`)
      .set(charge)
      return true;
  })

вы возвращали значение true платформе облачной функции, (указывая, что функция может быть прервана) до set() Асинхронная операция завершена.

...