TM-SGNL-iOS/SignalServiceKit/Subscriptions/Donations/Paypal+API.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

116 lines
4.6 KiB
Swift

//
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
// MARK: - Boost
public extension Paypal {
/// Create a payment and get a PayPal approval URL to present to the user.
static func createBoost(
amount: FiatMoney,
level: OneTimeBadgeLevel
) -> Promise<(URL, String)> {
firstly(on: DispatchQueue.sharedUserInitiated) {
let createBoostRequest = OWSRequestFactory.boostPaypalCreatePayment(
integerMoneyValue: DonationUtilities.integralAmount(for: amount),
inCurrencyCode: amount.currencyCode,
level: level.rawValue,
returnUrl: Self.webAuthReturnUrl,
cancelUrl: Self.webAuthCancelUrl
)
return SSKEnvironment.shared.networkManagerRef.makePromise(request: createBoostRequest)
}.map(on: DispatchQueue.sharedUserInitiated) { response throws -> (URL, String) in
guard let parser = ParamParser(responseObject: response.responseBodyJson) else {
throw OWSAssertionError("[Donations] Failed to decode JSON response")
}
let approvalUrlString: String = try parser.required(key: "approvalUrl")
let paymentId: String = try parser.required(key: "paymentId")
guard let approvalUrl = URL(string: approvalUrlString) else {
throw OWSAssertionError("[Donations] Approval URL was not a valid URL!")
}
return (approvalUrl, paymentId)
}
}
/// Confirms a payment after a successful authentication via PayPal's web
/// UI. Returns a payment ID that can be used to get receipt credentials.
static func confirmOneTimePayment(
amount: FiatMoney,
level: OneTimeBadgeLevel,
paymentId: String,
approvalParams: OneTimePaymentWebAuthApprovalParams
) -> Promise<String> {
firstly(on: DispatchQueue.sharedUserInitiated) {
let confirmOneTimePaymentRequest = OWSRequestFactory.oneTimePaypalConfirmPayment(
integerMoneyValue: DonationUtilities.integralAmount(for: amount),
inCurrencyCode: amount.currencyCode,
level: level.rawValue,
payerId: approvalParams.payerId,
paymentId: paymentId,
paymentToken: approvalParams.paymentToken
)
return SSKEnvironment.shared.networkManagerRef.makePromise(request: confirmOneTimePaymentRequest)
}.map(on: DispatchQueue.sharedUserInitiated) { response throws -> String in
guard let parser = ParamParser(responseObject: response.responseBodyJson) else {
throw OWSAssertionError("[Donations] Failed to decode JSON response")
}
return try parser.required(key: "paymentId")
}
}
}
// MARK: - Subscription
public extension Paypal {
struct SubscriptionAuthorizationParams {
/// A URL to present to the user to authorize the subscription.
public let approvalUrl: URL
/// An opaque ID identifying the payment method, for API calls after
/// subscription authorization.
public let paymentMethodId: String
}
/// Create a payment method entry with the Signal service for a subscription
/// processed by PayPal.
///
/// - Returns
/// PayPal params used to authorize payment for the new subscription.
static func createSignalPaymentMethodForSubscription(
subscriberId: Data
) -> Promise<SubscriptionAuthorizationParams> {
firstly {
let request = OWSRequestFactory.subscriptionCreatePaypalPaymentMethodRequest(
subscriberID: subscriberId,
returnURL: Self.webAuthReturnUrl,
cancelURL: Self.webAuthCancelUrl
)
return SSKEnvironment.shared.networkManagerRef.makePromise(request: request)
}.map(on: DispatchQueue.sharedUserInitiated) { response in
guard let parser = ParamParser(responseObject: response.responseBodyJson) else {
throw OWSAssertionError("[Donations] Missing or invalid response.")
}
guard let approvalUrl = URL(string: try parser.required(key: "approvalUrl")) else {
throw OWSAssertionError("[Donations] Approval URL string was not valid URL!")
}
let paymentMethodId: String = try parser.required(key: "token")
return SubscriptionAuthorizationParams(
approvalUrl: approvalUrl,
paymentMethodId: paymentMethodId
)
}
}
}