219 lines
5.7 KiB
TypeScript
219 lines
5.7 KiB
TypeScript
import { addReducer, getGlobal, setGlobal } from '../../../lib/teact/teactn';
|
|
|
|
import { PaymentStep } from '../../../types/index';
|
|
import { callApi } from '../../../api/gramjs';
|
|
import {
|
|
selectPaymentMessageId,
|
|
selectPaymentRequestId,
|
|
selectProviderPublishableKey,
|
|
selectStripeCredentials,
|
|
selectChatMessage,
|
|
} from '../../selectors';
|
|
|
|
import { getStripeError } from '../../helpers/payments';
|
|
import { buildQueryString } from '../../../util/requestQuery';
|
|
|
|
import {
|
|
updateShippingOptions,
|
|
setPaymentStep,
|
|
setRequestInfoId,
|
|
setPaymentForm,
|
|
setStripeCardInfo,
|
|
setInvoiceMessageInfo,
|
|
setReceipt,
|
|
clearPayment,
|
|
closeInvoice,
|
|
} from '../../reducers';
|
|
|
|
addReducer('validateRequestedInfo', (global, actions, payload) => {
|
|
const { requestInfo, saveInfo } = payload;
|
|
const messageId = selectPaymentMessageId(global);
|
|
if (!messageId) {
|
|
return;
|
|
}
|
|
validateRequestedInfo(messageId, requestInfo, saveInfo);
|
|
});
|
|
|
|
async function validateRequestedInfo(messageId: number, requestInfo: any, shouldSave?: true) {
|
|
const result = await callApi('validateRequestedInfo', { messageId, requestInfo, shouldSave });
|
|
if (!result) {
|
|
return;
|
|
}
|
|
const { id, shippingOptions } = result;
|
|
if (!id) {
|
|
return;
|
|
}
|
|
let global = setRequestInfoId(getGlobal(), id);
|
|
if (shippingOptions) {
|
|
global = updateShippingOptions(global, shippingOptions);
|
|
global = setPaymentStep(global, PaymentStep.Shipping);
|
|
} else {
|
|
global = setPaymentStep(global, PaymentStep.PaymentInfo);
|
|
}
|
|
setGlobal(global);
|
|
}
|
|
|
|
addReducer('getPaymentForm', (global, actions, payload) => {
|
|
const { messageId } = payload;
|
|
if (!messageId) {
|
|
return;
|
|
}
|
|
getPaymentForm(messageId);
|
|
});
|
|
|
|
|
|
async function getPaymentForm(messageId: number) {
|
|
const result = await callApi('getPaymentForm', { messageId });
|
|
if (!result) {
|
|
return;
|
|
}
|
|
let global = setPaymentForm(getGlobal(), result);
|
|
let step = PaymentStep.PaymentInfo;
|
|
if (global.payment.invoice
|
|
&& (global.payment.invoice.shippingAddressRequested
|
|
|| global.payment.invoice.nameRequested
|
|
|| global.payment.invoice.phoneRequested
|
|
|| global.payment.invoice.emailRequested)) {
|
|
step = PaymentStep.ShippingInfo;
|
|
}
|
|
global = setPaymentStep(global, step);
|
|
setGlobal(global);
|
|
}
|
|
|
|
addReducer('getReceipt', (global, actions, payload) => {
|
|
const { receiptMessageId, chatId, messageId } = payload;
|
|
if (!messageId || !receiptMessageId || !chatId) {
|
|
return;
|
|
}
|
|
getReceipt(messageId, receiptMessageId, chatId);
|
|
});
|
|
|
|
async function getReceipt(messageId: number, receiptMessageId: number, chatId: number) {
|
|
const result = await callApi('getReceipt', receiptMessageId);
|
|
if (!result) {
|
|
return;
|
|
}
|
|
let global = getGlobal();
|
|
const message = selectChatMessage(global, chatId, messageId);
|
|
global = setReceipt(global, result, message);
|
|
setGlobal(global);
|
|
}
|
|
|
|
addReducer('clearPaymentError', (global) => {
|
|
setGlobal({
|
|
...global,
|
|
payment: {
|
|
...global.payment,
|
|
error: undefined,
|
|
},
|
|
});
|
|
});
|
|
|
|
addReducer('clearReceipt', (global) => {
|
|
setGlobal({
|
|
...global,
|
|
payment: {
|
|
...global.payment,
|
|
receipt: undefined,
|
|
},
|
|
});
|
|
});
|
|
|
|
addReducer('sendCredentialsInfo', (global, actions, payload) => {
|
|
const publishableKey = selectProviderPublishableKey(global);
|
|
if (!publishableKey) {
|
|
return;
|
|
}
|
|
const { credentials } = payload;
|
|
const { data } = credentials;
|
|
sendStipeCredentials(data, publishableKey);
|
|
});
|
|
|
|
addReducer('sendPaymentForm', (global, actions, payload) => {
|
|
const { shippingOptionId, saveCredentials } = payload;
|
|
const messageId = selectPaymentMessageId(global);
|
|
const requestInfoId = selectPaymentRequestId(global);
|
|
const publishableKey = selectProviderPublishableKey(global);
|
|
const stripeCredentials = selectStripeCredentials(global);
|
|
if (!messageId || !publishableKey) {
|
|
return;
|
|
}
|
|
sendPaymentForm(messageId, {
|
|
save: saveCredentials,
|
|
data: stripeCredentials,
|
|
}, requestInfoId, shippingOptionId);
|
|
});
|
|
|
|
async function sendStipeCredentials(data: {
|
|
cardNumber: string;
|
|
cardholder?: string;
|
|
expiryMonth: string;
|
|
expiryYear: string;
|
|
cvv: string;
|
|
country: string;
|
|
zip: string;
|
|
},
|
|
publishableKey: string) {
|
|
const query = buildQueryString({
|
|
'card[number]': data.cardNumber,
|
|
'card[exp_month]': data.expiryMonth,
|
|
'card[exp_year]': data.expiryYear,
|
|
'card[cvc]': data.cvv,
|
|
'card[address_zip]': data.zip,
|
|
'card[address_country]': data.country,
|
|
});
|
|
|
|
const response = await fetch(`https://api.stripe.com/v1/tokens${query}`, {
|
|
method: 'POST',
|
|
credentials: 'same-origin',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
Authorization: `Bearer ${publishableKey}`,
|
|
},
|
|
});
|
|
const result = await response.json();
|
|
if (result.error) {
|
|
const error = getStripeError(result.error);
|
|
const global = getGlobal();
|
|
setGlobal({
|
|
...global,
|
|
payment: {
|
|
...global.payment,
|
|
error: {
|
|
...error,
|
|
},
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
let global = setStripeCardInfo(getGlobal(), {
|
|
type: result.type,
|
|
id: result.id,
|
|
});
|
|
global = setPaymentStep(global, PaymentStep.Checkout);
|
|
setGlobal(global);
|
|
}
|
|
|
|
async function sendPaymentForm(
|
|
messageId: number,
|
|
credentials: any,
|
|
requestedInfoId?: string,
|
|
shippingOptionId?: string,
|
|
) {
|
|
const result = await callApi('sendPaymentForm', {
|
|
messageId, credentials, requestedInfoId, shippingOptionId,
|
|
});
|
|
if (result) {
|
|
const global = clearPayment(getGlobal());
|
|
setGlobal(closeInvoice(global));
|
|
}
|
|
}
|
|
|
|
addReducer('setPaymentStep', (global, actions, payload = {}) => {
|
|
return setPaymentStep(global, payload.step || PaymentStep.ShippingInfo);
|
|
});
|
|
|
|
addReducer('setInvoiceMessageInfo', (global, actions, payload) => {
|
|
return setInvoiceMessageInfo(global, payload);
|
|
});
|