commit d5af2295113c5fae1df23ac506cad7a69c1c570f
parent a06aff28aee937ca5a5806bcf589c9713f91a4e9
Author: Marc Stibane <marc@taler.net>
Date: Fri, 7 Aug 2026 08:57:17 +0200
PaymentScan
Diffstat:
4 files changed, 330 insertions(+), 330 deletions(-)
diff --git a/TalerWallet1/Views/Sheets/Payment/PayTemplateScan.swift b/TalerWallet1/Views/Sheets/Payment/PayTemplateScan.swift
@@ -116,7 +116,7 @@ struct PayTemplateScan: View {
let amountLabel = minimalistic ? String(localized: "Amount:")
: a11yLabel
// final destination with amountToTransfer, after user input of amount
- let finalDestinationI = PaymentView(stack: stack.push(),
+ let finalDestinationI = PaymentScan(stack: stack.push(),
url: url,
template: true,
amountToTransfer: $amountToTransfer,
@@ -125,7 +125,7 @@ struct PayTemplateScan: View {
summaryIsEditable: summaryIsEditable)
// final destination with amountShortcut, when user tapped a shortcut
- let finalDestinationS = PaymentView(stack: stack.push(),
+ let finalDestinationS = PaymentScan(stack: stack.push(),
url: url,
template: true,
amountToTransfer: $amountShortcut,
@@ -190,7 +190,7 @@ struct PayTemplateScan: View {
} // inputDestination
} else { // both template contract amount and summary are fixed => directly show the payment
// Attention: contains a List, thus mustn't be included in a ScrollView
- PaymentView(stack: stack.push(),
+ PaymentScan(stack: stack.push(),
url: url,
template: true,
amountToTransfer: $amountToTransfer,
diff --git a/TalerWallet1/Views/Sheets/Payment/PaymentScan.swift b/TalerWallet1/Views/Sheets/Payment/PaymentScan.swift
@@ -0,0 +1,326 @@
+/*
+ * This file is part of GNU Taler, ©2022-26 Taler Systems S.A.
+ * See LICENSE.md
+ */
+/**
+ * @author Marc Stibane
+ */
+import SwiftUI
+import taler_swift
+import SymLog
+
+typealias Announce = (_ this: String) -> ()
+
+fileprivate func feeLabel(_ feeString: String) -> String {
+ feeString.isEmpty ? EMPTYSTRING : String(localized: "+ \(feeString) fee")
+}
+
+// MARK: -
+// Will be called either by the user scanning a <pay> QR code or tapping the provided link,
+// both from the shop's website - or even from a printed QR code.
+// We show the payment details in a sheet, and a "Confirm payment" / "Pay now" button.
+// This is also the final view after the user entered data of a <pay-template>.
+struct PaymentScan: View, Sendable {
+ private let symLog = SymLogV(0)
+ let stack: CallStack
+
+ // the scanned URL
+ let url: URL
+ let template: Bool
+ @Binding var amountToTransfer: Amount
+ @Binding var summary: String
+ let amountIsEditable: Bool //
+ let summaryIsEditable: Bool //
+
+ @EnvironmentObject private var model: WalletModel
+ @EnvironmentObject private var controller: Controller
+ @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
+
+ @State private var currencyInfo: CurrencyInfo = CurrencyInfo.zero(UNKNOWN)
+ @State var txId: String? = nil
+
+ @State private var elapsed: Int = 0
+ @State private var talerTX = TalerTransaction(dummyCurrency: DEMOCURRENCY)
+
+ @MainActor
+ private func viewDidLoad() async {
+// symLog.log(".task")
+ if template {
+ if let templateResponse = try? await model.preparePayForTemplate(url.trimmedString,
+ amount: amountIsEditable ? amountToTransfer : nil,
+ summary: summaryIsEditable ? summary : nil) {
+ txId = templateResponse.transactionId
+// preparePayResult = templateResponse
+// let raw = templateResponse.amountRaw
+// controller.updateAmount(raw, forSaved: url)
+ }
+ } else {
+ if let payResponse = try? await model.preparePayForUri(url.trimmedString) {
+ txId = payResponse.transactionId
+// let raw = payResponse.amountRaw
+// controller.updateAmount(raw, forSaved: url) // TODO: update scanned URL
+ }
+ }
+ }
+
+ var body: some View {
+ ZStack {
+ if let txId {
+ TransactionSummaryList(stack: stack.push(),
+ transactionId: txId,
+ talerTX: $talerTX,
+ navTitle: nil,
+ hasDone: true, // conclude payment
+ showDone: .prominent,
+ url: url,
+ withActions: false)
+#if TALER_NIGHTLY2
+// if let preparePayResult {
+ let status = preparePayResult.status
+ let paid = status == .alreadyConfirmed
+ let navTitle = paid ? String(localized: "Already paid", comment:"pay merchant navTitle")
+ : String(localized: "Confirm Payment", comment:"pay merchant navTitle")
+ let list = List {
+ TransactionSummaryList.MerchantHeader(terms: terms)
+
+ if paid {
+ Text("You already paid for this article.")
+ .talerFont(.headline)
+ if let fulfillmentUrl = terms.fulfillmentURL {
+ if let destination = URL(string: fulfillmentUrl) {
+ let buttonTitle = terms.fulfillmentMessage ?? String(localized: "Open merchant website")
+ Link(buttonTitle, destination: destination)
+ .buttonStyle(TalerButtonStyle(type: .bordered))
+ .accessibilityHint(String(localized: "Will go to the merchant website.", comment: "a11y"))
+ }
+ }
+ } // You already paid
+
+ }
+ .listStyle(myListStyle.style).anyView
+#if OIM
+ .overlay { if #available(iOS 16.4, *) {
+ if controller.oimSheetActive {
+ OIMpayView(stack: stack.push(),
+ amount: effective)
+ }
+ } }
+#endif
+
+ if #available(iOS 17.0, *) {
+ list.toolbarTitleDisplayMode(.inlineLarge)
+ } else {
+ list
+ }
+#endif
+ } else {
+ LoadingView(stack: stack.push(), scopeInfo: nil, message: url.host)
+ .task { await viewDidLoad() }
+ }
+ }.onAppear() {
+ symLog.log("onAppear")
+ DebugViewC.shared.setSheetID(SHEET_PAYMENT, stack: stack.push())
+ }
+ }
+}
+// MARK: -
+// MARK: -
+struct PaymentView2: View, Sendable {
+ let stack: CallStack
+ let paid: Bool
+ let raw: Amount
+ let effective: Amount?
+ let firstScope: ScopeInfo?
+ let baseURL: String?
+// let terms: MerchantContractTerms
+ let summary: String?
+ let products: [Product]?
+ let balanceDetails: PaymentInsufficientBalanceDetails?
+
+ func computeFee(raw: Amount?, eff: Amount?) -> Amount? {
+ if let raw, let eff {
+ return try! Amount.diff(raw, eff) // TODO: different currencies
+ }
+ return nil
+ }
+
+ var body: some View {
+ // TODO: show balanceDetails.balanceAvailable
+ let topTitle = paid ? String(localized: "Paid amount:")
+ : String(localized: "Amount to pay:")
+ let topAbbrev = paid ? String(localized: "Paid:", comment: "mini")
+ : String(localized: "Pay:", comment: "mini")
+ let bottomTitle = paid ? String(localized: "Spent amount:")
+ : String(localized: "Amount to spend:")
+ if let effective { // payment possible
+ let fee = computeFee(raw: raw, eff: effective)
+ ThreeAmountsSection(stack: stack.push("PaymentView2"),
+ scope: firstScope,
+ topTitle: topTitle,
+ topAbbrev: topAbbrev,
+ topAmount: raw,
+ noFees: nil, // TODO: check baseURL for fees
+ fee: fee,
+ feeIsNegative: nil,
+ bottomTitle: bottomTitle,
+ bottomAbbrev: String(localized: "Effective:", comment: "mini"),
+ bottomAmount: effective,
+ large: false,
+ pendingDialog: !paid,
+ isDone: paid,
+ incoming: false,
+ baseURL: baseURL,
+ txStateLcl: nil,
+ summary: nil, // summary already shown in PaymentView above choices
+ products: products)
+ // TODO: payment: popup with all possible exchanges, check fees
+ } else if let balanceDetails { // Insufficient
+ if let localizedCause = balanceDetails.causeHint?.localizedCause(raw.currencyStr) {
+ Text(localizedCause)
+ .talerFont(.headline)
+ }
+ ThreeAmountsSection(stack: stack.push(),
+ scope: firstScope,
+ topTitle: topTitle,
+ topAbbrev: topAbbrev,
+ topAmount: raw,
+ noFees: nil, // TODO: check baseURL for fees
+ fee: nil,
+ feeIsNegative: nil,
+ bottomTitle: String(localized: "Amount available:"),
+ bottomAbbrev: String(localized: "Available:", comment: "mini"),
+ bottomAmount: balanceDetails.balanceAvailable,
+ large: false,
+ pendingDialog: false, // TODO: true to always show currency the payment will be made in?
+ isDone: false,
+ incoming: false,
+ baseURL: baseURL,
+ txStateLcl: nil,
+ summary: nil, // summary already shown in PaymentView above choices
+ products: products)
+ } else {
+ // TODO: Error - neither effective nor balanceDetails
+ Text("Error")
+ .talerFont(.body)
+ }
+ }
+}
+// MARK: -
+struct PaySafeArea: View, Sendable {
+ let symLog: SymLogV?
+ let stack: CallStack
+ let terms: MerchantContractTerms
+ let amountString: String
+ let amountA11y: String
+ @Binding var payNow: Bool
+ @State private var wasTapped: Bool = false
+
+ func timeToPay(_ terms: MerchantContractTerms) -> Int {
+ if let milliseconds = try? terms.payDeadline.milliseconds() {
+ let date = Date(milliseconds: milliseconds)
+ let now = Date.now
+ let timeInterval = now.timeIntervalSince(date)
+ if timeInterval < 0 {
+ symLog?.log("\(timeInterval) seconds left to pay")
+ return Int(-timeInterval)
+ } else {
+ symLog?.log("\(date) - \(now) = \(timeInterval)")
+ }
+ } else {
+ symLog?.log("no milliseconds")
+ }
+ return 0
+ }
+
+ var body: some View {
+ let timeToPay = timeToPay(terms)
+ let showTime = timeToPay > 0 && timeToPay < 300
+ let button = Button("Pay \(amountString) now") {
+ if !wasTapped {
+ wasTapped = true
+ symLog?.log("paying \(amountString) now")
+ payNow = true
+ }
+ }
+ .accessibilityLabel(Text("Pay \(amountA11y) now", comment: "a11y"))
+ .buttonStyle(TalerButtonStyle(type: .prominent))
+ .disabled(wasTapped)
+ .padding(.horizontal)
+
+ if showTime {
+ let view = VStack {
+ TimeView(String(localized: "Time to pay:"),
+ seconds: timeToPay)
+ .padding(.top)
+ button
+ .padding(.bottom, 4)
+ }
+ if #available(iOS 26.0, *) {
+ view
+ .glassEffect(in: .rect(cornerRadius: 16.0))
+ .padding(.horizontal)
+ } else {
+ view
+ }
+ } else {
+ let _ = symLog?.log("\(timeToPay) not shown")
+ button
+ }
+ }
+}
+// MARK: -
+#if false
+struct PaymentURIView_Previews: PreviewProvider {
+ static var previews: some View {
+ let merchant = Merchant(name: "Merchant")
+ let extra = Extra(articleName: "articleName")
+ let product = Product(description: "description")
+ let terms = MerchantContractTerms(hWire: "hWire",
+ wireMethod: "wireMethod",
+ summary: "summary",
+ summaryI18n: nil,
+ nonce: "nonce",
+ amount: Amount(currency: LONGCURRENCY, cent: 220),
+ payDeadline: Timestamp.tomorrow(),
+ maxFee: Amount(currency: LONGCURRENCY, cent: 20),
+ merchant: merchant,
+ merchantPub: "merchantPub",
+ deliveryDate: nil,
+ deliveryLocation: nil,
+ exchanges: [],
+ products: [product],
+ refundDeadline: Timestamp.tomorrow(),
+ wireTransferDeadline: Timestamp.tomorrow(),
+ timestamp: Timestamp.now(),
+ orderID: "orderID",
+ merchantBaseURL: "merchantBaseURL",
+ fulfillmentURL: "fulfillmentURL",
+ publicReorderURL: "publicReorderURL",
+ fulfillmentMessage: nil,
+ fulfillmentMessageI18n: nil,
+ minimumAge: nil
+// extra: extra,
+// auditors: []
+ )
+ let details = PreparePayResult(status: PreparePayResultType.paymentPossible,
+ transactionId: "txn:payment:012345",
+ contractTerms: terms,
+ contractTermsHash: "termsHash",
+ amountRaw: Amount(currency: LONGCURRENCY, cent: 220),
+ amountEffective: Amount(currency: LONGCURRENCY, cent: 240),
+ balanceDetails: nil,
+ paid: nil
+// , talerUri: "talerURI"
+ )
+ let url = URL(string: "taler://pay/some_amount")!
+
+// @State private var amount: Amount? = nil // templateParam
+// @State private var summary: String? = nil // templateParam
+
+ PaymentView(stack: CallStack("Preview"), url: url,
+ template: false, amountToTransfer: nil, summary: nil,
+ amountIsEditable: false, summaryIsEditable: false,
+ preparePayResult: details)
+ }
+}
+#endif
diff --git a/TalerWallet1/Views/Sheets/Payment/PaymentView.swift b/TalerWallet1/Views/Sheets/Payment/PaymentView.swift
@@ -1,326 +0,0 @@
-/*
- * This file is part of GNU Taler, ©2022-26 Taler Systems S.A.
- * See LICENSE.md
- */
-/**
- * @author Marc Stibane
- */
-import SwiftUI
-import taler_swift
-import SymLog
-
-typealias Announce = (_ this: String) -> ()
-
-fileprivate func feeLabel(_ feeString: String) -> String {
- feeString.isEmpty ? EMPTYSTRING : String(localized: "+ \(feeString) fee")
-}
-
-// MARK: -
-// Will be called either by the user scanning a <pay> QR code or tapping the provided link,
-// both from the shop's website - or even from a printed QR code.
-// We show the payment details in a sheet, and a "Confirm payment" / "Pay now" button.
-// This is also the final view after the user entered data of a <pay-template>.
-struct PaymentView: View, Sendable {
- private let symLog = SymLogV(0)
- let stack: CallStack
-
- // the scanned URL
- let url: URL
- let template: Bool
- @Binding var amountToTransfer: Amount
- @Binding var summary: String
- let amountIsEditable: Bool //
- let summaryIsEditable: Bool //
-
- @EnvironmentObject private var model: WalletModel
- @EnvironmentObject private var controller: Controller
- @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
-
- @State private var currencyInfo: CurrencyInfo = CurrencyInfo.zero(UNKNOWN)
- @State var txId: String? = nil
-
- @State private var elapsed: Int = 0
- @State private var talerTX = TalerTransaction(dummyCurrency: DEMOCURRENCY)
-
- @MainActor
- private func viewDidLoad() async {
-// symLog.log(".task")
- if template {
- if let templateResponse = try? await model.preparePayForTemplate(url.trimmedString,
- amount: amountIsEditable ? amountToTransfer : nil,
- summary: summaryIsEditable ? summary : nil) {
- txId = templateResponse.transactionId
-// preparePayResult = templateResponse
-// let raw = templateResponse.amountRaw
-// controller.updateAmount(raw, forSaved: url)
- }
- } else {
- if let payResponse = try? await model.preparePayForUri(url.trimmedString) {
- txId = payResponse.transactionId
-// let raw = payResponse.amountRaw
-// controller.updateAmount(raw, forSaved: url) // TODO: update scanned URL
- }
- }
- }
-
- var body: some View {
- ZStack {
- if let txId {
- TransactionSummaryList(stack: stack.push(),
- transactionId: txId,
- talerTX: $talerTX,
- navTitle: nil,
- hasDone: true, // conclude payment
- showDone: .prominent,
- url: url,
- withActions: false)
-#if TALER_NIGHTLY2
-// if let preparePayResult {
- let status = preparePayResult.status
- let paid = status == .alreadyConfirmed
- let navTitle = paid ? String(localized: "Already paid", comment:"pay merchant navTitle")
- : String(localized: "Confirm Payment", comment:"pay merchant navTitle")
- let list = List {
- TransactionSummaryList.MerchantHeader(terms: terms)
-
- if paid {
- Text("You already paid for this article.")
- .talerFont(.headline)
- if let fulfillmentUrl = terms.fulfillmentURL {
- if let destination = URL(string: fulfillmentUrl) {
- let buttonTitle = terms.fulfillmentMessage ?? String(localized: "Open merchant website")
- Link(buttonTitle, destination: destination)
- .buttonStyle(TalerButtonStyle(type: .bordered))
- .accessibilityHint(String(localized: "Will go to the merchant website.", comment: "a11y"))
- }
- }
- } // You already paid
-
- }
- .listStyle(myListStyle.style).anyView
-#if OIM
- .overlay { if #available(iOS 16.4, *) {
- if controller.oimSheetActive {
- OIMpayView(stack: stack.push(),
- amount: effective)
- }
- } }
-#endif
-
- if #available(iOS 17.0, *) {
- list.toolbarTitleDisplayMode(.inlineLarge)
- } else {
- list
- }
-#endif
- } else {
- LoadingView(stack: stack.push(), scopeInfo: nil, message: url.host)
- .task { await viewDidLoad() }
- }
- }.onAppear() {
- symLog.log("onAppear")
- DebugViewC.shared.setSheetID(SHEET_PAYMENT, stack: stack.push())
- }
- }
-}
-// MARK: -
-// MARK: -
-struct PaymentView2: View, Sendable {
- let stack: CallStack
- let paid: Bool
- let raw: Amount
- let effective: Amount?
- let firstScope: ScopeInfo?
- let baseURL: String?
-// let terms: MerchantContractTerms
- let summary: String?
- let products: [Product]?
- let balanceDetails: PaymentInsufficientBalanceDetails?
-
- func computeFee(raw: Amount?, eff: Amount?) -> Amount? {
- if let raw, let eff {
- return try! Amount.diff(raw, eff) // TODO: different currencies
- }
- return nil
- }
-
- var body: some View {
- // TODO: show balanceDetails.balanceAvailable
- let topTitle = paid ? String(localized: "Paid amount:")
- : String(localized: "Amount to pay:")
- let topAbbrev = paid ? String(localized: "Paid:", comment: "mini")
- : String(localized: "Pay:", comment: "mini")
- let bottomTitle = paid ? String(localized: "Spent amount:")
- : String(localized: "Amount to spend:")
- if let effective { // payment possible
- let fee = computeFee(raw: raw, eff: effective)
- ThreeAmountsSection(stack: stack.push("PaymentView2"),
- scope: firstScope,
- topTitle: topTitle,
- topAbbrev: topAbbrev,
- topAmount: raw,
- noFees: nil, // TODO: check baseURL for fees
- fee: fee,
- feeIsNegative: nil,
- bottomTitle: bottomTitle,
- bottomAbbrev: String(localized: "Effective:", comment: "mini"),
- bottomAmount: effective,
- large: false,
- pendingDialog: !paid,
- isDone: paid,
- incoming: false,
- baseURL: baseURL,
- txStateLcl: nil,
- summary: nil, // summary already shown in PaymentView above choices
- products: products)
- // TODO: payment: popup with all possible exchanges, check fees
- } else if let balanceDetails { // Insufficient
- if let localizedCause = balanceDetails.causeHint?.localizedCause(raw.currencyStr) {
- Text(localizedCause)
- .talerFont(.headline)
- }
- ThreeAmountsSection(stack: stack.push(),
- scope: firstScope,
- topTitle: topTitle,
- topAbbrev: topAbbrev,
- topAmount: raw,
- noFees: nil, // TODO: check baseURL for fees
- fee: nil,
- feeIsNegative: nil,
- bottomTitle: String(localized: "Amount available:"),
- bottomAbbrev: String(localized: "Available:", comment: "mini"),
- bottomAmount: balanceDetails.balanceAvailable,
- large: false,
- pendingDialog: false, // TODO: true to always show currency the payment will be made in?
- isDone: false,
- incoming: false,
- baseURL: baseURL,
- txStateLcl: nil,
- summary: nil, // summary already shown in PaymentView above choices
- products: products)
- } else {
- // TODO: Error - neither effective nor balanceDetails
- Text("Error")
- .talerFont(.body)
- }
- }
-}
-// MARK: -
-struct PaySafeArea: View, Sendable {
- let symLog: SymLogV?
- let stack: CallStack
- let terms: MerchantContractTerms
- let amountString: String
- let amountA11y: String
- @Binding var payNow: Bool
- @State private var wasTapped: Bool = false
-
- func timeToPay(_ terms: MerchantContractTerms) -> Int {
- if let milliseconds = try? terms.payDeadline.milliseconds() {
- let date = Date(milliseconds: milliseconds)
- let now = Date.now
- let timeInterval = now.timeIntervalSince(date)
- if timeInterval < 0 {
- symLog?.log("\(timeInterval) seconds left to pay")
- return Int(-timeInterval)
- } else {
- symLog?.log("\(date) - \(now) = \(timeInterval)")
- }
- } else {
- symLog?.log("no milliseconds")
- }
- return 0
- }
-
- var body: some View {
- let timeToPay = timeToPay(terms)
- let showTime = timeToPay > 0 && timeToPay < 300
- let button = Button("Pay \(amountString) now") {
- if !wasTapped {
- wasTapped = true
- symLog?.log("paying \(amountString) now")
- payNow = true
- }
- }
- .accessibilityLabel(Text("Pay \(amountA11y) now", comment: "a11y"))
- .buttonStyle(TalerButtonStyle(type: .prominent))
- .disabled(wasTapped)
- .padding(.horizontal)
-
- if showTime {
- let view = VStack {
- TimeView(String(localized: "Time to pay:"),
- seconds: timeToPay)
- .padding(.top)
- button
- .padding(.bottom, 4)
- }
- if #available(iOS 26.0, *) {
- view
- .glassEffect(in: .rect(cornerRadius: 16.0))
- .padding(.horizontal)
- } else {
- view
- }
- } else {
- let _ = symLog?.log("\(timeToPay) not shown")
- button
- }
- }
-}
-// MARK: -
-#if false
-struct PaymentURIView_Previews: PreviewProvider {
- static var previews: some View {
- let merchant = Merchant(name: "Merchant")
- let extra = Extra(articleName: "articleName")
- let product = Product(description: "description")
- let terms = MerchantContractTerms(hWire: "hWire",
- wireMethod: "wireMethod",
- summary: "summary",
- summaryI18n: nil,
- nonce: "nonce",
- amount: Amount(currency: LONGCURRENCY, cent: 220),
- payDeadline: Timestamp.tomorrow(),
- maxFee: Amount(currency: LONGCURRENCY, cent: 20),
- merchant: merchant,
- merchantPub: "merchantPub",
- deliveryDate: nil,
- deliveryLocation: nil,
- exchanges: [],
- products: [product],
- refundDeadline: Timestamp.tomorrow(),
- wireTransferDeadline: Timestamp.tomorrow(),
- timestamp: Timestamp.now(),
- orderID: "orderID",
- merchantBaseURL: "merchantBaseURL",
- fulfillmentURL: "fulfillmentURL",
- publicReorderURL: "publicReorderURL",
- fulfillmentMessage: nil,
- fulfillmentMessageI18n: nil,
- minimumAge: nil
-// extra: extra,
-// auditors: []
- )
- let details = PreparePayResult(status: PreparePayResultType.paymentPossible,
- transactionId: "txn:payment:012345",
- contractTerms: terms,
- contractTermsHash: "termsHash",
- amountRaw: Amount(currency: LONGCURRENCY, cent: 220),
- amountEffective: Amount(currency: LONGCURRENCY, cent: 240),
- balanceDetails: nil,
- paid: nil
-// , talerUri: "talerURI"
- )
- let url = URL(string: "taler://pay/some_amount")!
-
-// @State private var amount: Amount? = nil // templateParam
-// @State private var summary: String? = nil // templateParam
-
- PaymentView(stack: CallStack("Preview"), url: url,
- template: false, amountToTransfer: nil, summary: nil,
- amountIsEditable: false, summaryIsEditable: false,
- preparePayResult: details)
- }
-}
-#endif
diff --git a/TalerWallet1/Views/Sheets/URLSheet.swift b/TalerWallet1/Views/Sheets/URLSheet.swift
@@ -70,7 +70,7 @@ struct URLSheet: View {
selectedBalance: selectedBalance,
url: passedURL)
case .pay:
- PaymentView(stack: stack.push(), url: passedURL,
+ PaymentScan(stack: stack.push(), url: passedURL,
template: false, amountToTransfer: $amountToTransfer, summary: $summary,
amountIsEditable: false, summaryIsEditable: false)
case .payPull: