107 lines
4.1 KiB
Swift
107 lines
4.1 KiB
Swift
//
|
|
// Copyright (c) 2021 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import PassKit
|
|
import SignalCoreKit
|
|
|
|
public class DonationUtilities: NSObject {
|
|
public static var isApplePayAvailable: Bool {
|
|
PKPaymentAuthorizationController.canMakePayments()
|
|
}
|
|
|
|
public static let supportedNetworks: [PKPaymentNetwork] = [
|
|
.visa,
|
|
.masterCard,
|
|
.amex,
|
|
.discover,
|
|
.JCB,
|
|
.interac
|
|
]
|
|
|
|
public enum Symbol: Equatable {
|
|
case before(String)
|
|
case after(String)
|
|
case currencyCode
|
|
}
|
|
|
|
public struct Presets {
|
|
public struct Preset {
|
|
public let symbol: Symbol
|
|
public let amounts: [UInt]
|
|
}
|
|
|
|
public static let presets: [Currency.Code: Preset] = [
|
|
"USD": Preset(symbol: .before("$"), amounts: [3, 5, 10, 20, 50, 100]),
|
|
"AUD": Preset(symbol: .before("A$"), amounts: [5, 10, 15, 25, 65, 125]),
|
|
"BRL": Preset(symbol: .before("R$"), amounts: [15, 25, 50, 100, 250, 525]),
|
|
"GBP": Preset(symbol: .before("£"), amounts: [3, 5, 10, 15, 35, 70]),
|
|
"CAD": Preset(symbol: .before("CA$"), amounts: [5, 10, 15, 25, 60, 125]),
|
|
"CNY": Preset(symbol: .before("CN¥"), amounts: [20, 35, 65, 130, 320, 650]),
|
|
"EUR": Preset(symbol: .before("€"), amounts: [3, 5, 10, 15, 40, 80]),
|
|
"HKD": Preset(symbol: .before("HK$"), amounts: [25, 40, 80, 150, 400, 775]),
|
|
"INR": Preset(symbol: .before("₹"), amounts: [100, 200, 300, 500, 1_000, 5_000]),
|
|
"JPY": Preset(symbol: .before("¥"), amounts: [325, 550, 1_000, 2_200, 5_500, 11_000]),
|
|
"KRW": Preset(symbol: .before("₩"), amounts: [3_500, 5_500, 11_000, 22_500, 55_500, 100_000]),
|
|
"PLN": Preset(symbol: .after("zł"), amounts: [10, 20, 40, 75, 150, 375]),
|
|
"SEK": Preset(symbol: .after("kr"), amounts: [25, 50, 75, 150, 400, 800]),
|
|
"CHF": Preset(symbol: .currencyCode, amounts: [3, 5, 10, 20, 50, 100])
|
|
]
|
|
|
|
public static func symbol(for code: Currency.Code) -> Symbol {
|
|
presets[code]?.symbol ?? .currencyCode
|
|
}
|
|
}
|
|
|
|
private static let currencyFormatter: NumberFormatter = {
|
|
let currencyFormatter = NumberFormatter()
|
|
currencyFormatter.numberStyle = .decimal
|
|
return currencyFormatter
|
|
}()
|
|
|
|
public static func formatCurrency(_ value: NSDecimalNumber, currencyCode: Currency.Code, includeSymbol: Bool = true) -> String {
|
|
let isZeroDecimalCurrency = Stripe.zeroDecimalCurrencyCodes.contains(currencyCode)
|
|
|
|
let decimalPlaces: Int
|
|
if isZeroDecimalCurrency {
|
|
decimalPlaces = 0
|
|
} else if value.doubleValue == Double(value.intValue) {
|
|
decimalPlaces = 0
|
|
} else {
|
|
decimalPlaces = 2
|
|
}
|
|
|
|
currencyFormatter.minimumFractionDigits = decimalPlaces
|
|
currencyFormatter.maximumFractionDigits = decimalPlaces
|
|
|
|
let valueString = currencyFormatter.string(from: value) ?? value.stringValue
|
|
|
|
guard includeSymbol else { return valueString }
|
|
|
|
switch Presets.symbol(for: currencyCode) {
|
|
case .before(let symbol): return symbol + valueString
|
|
case .after(let symbol): return valueString + symbol
|
|
case .currencyCode: return currencyCode + " " + valueString
|
|
}
|
|
}
|
|
|
|
public static func newPaymentRequest(for amount: NSDecimalNumber, currencyCode: String) -> PKPaymentRequest {
|
|
let request = PKPaymentRequest()
|
|
request.paymentSummaryItems = [PKPaymentSummaryItem(
|
|
label: NSLocalizedString(
|
|
"DONATION_VIEW_DONATION_TO_SIGNAL",
|
|
comment: "Text describing to the user that they're going to pay a donation to Signal"
|
|
),
|
|
amount: amount,
|
|
type: .final
|
|
)]
|
|
request.merchantIdentifier = "merchant.org.signalfoundation"
|
|
request.merchantCapabilities = .capability3DS
|
|
request.countryCode = "US"
|
|
request.currencyCode = currencyCode
|
|
request.supportedNetworks = DonationUtilities.supportedNetworks
|
|
return request
|
|
}
|
|
}
|