From dd86ead7d8b356b33b99558df2ca42a1b8b15683 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 18 Feb 2018 20:20:04 -0500 Subject: [PATCH] Add popmoney (#1273) --- common/src/main/proto/pb.proto | 6 + .../resources/i18n/displayStrings.properties | 5 + .../core/payment/PaymentAccountFactory.java | 2 + .../io/bisq/core/payment/PopmoneyAccount.java | 54 +++++++++ .../core/payment/payload/PaymentMethod.java | 3 + .../payload/PopmoneyAccountPayload.java | 103 ++++++++++++++++ .../payment/payload/VenmoAccountPayload.java | 2 +- .../io/bisq/core/proto/CoreProtoResolver.java | 2 + .../paymentmethods/PopmoneyForm.java | 114 ++++++++++++++++++ .../fiataccounts/FiatAccountsView.java | 5 + .../steps/buyer/BuyerStep2View.java | 3 + .../util/validation/PopmoneyValidator.java | 28 +++++ 12 files changed, 326 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/io/bisq/core/payment/PopmoneyAccount.java create mode 100644 core/src/main/java/io/bisq/core/payment/payload/PopmoneyAccountPayload.java create mode 100644 gui/src/main/java/io/bisq/gui/components/paymentmethods/PopmoneyForm.java create mode 100644 gui/src/main/java/io/bisq/gui/util/validation/PopmoneyValidator.java diff --git a/common/src/main/proto/pb.proto b/common/src/main/proto/pb.proto index adbb99ffaff..d75a71bcfe0 100644 --- a/common/src/main/proto/pb.proto +++ b/common/src/main/proto/pb.proto @@ -834,6 +834,7 @@ message PaymentAccountPayload { CashAppAccountPayload cash_app_account_payload = 17; MoneyBeamAccountPayload money_beam_account_payload = 18; VenmoAccountPayload venmo_account_payload = 19; + PopmoneyAccountPayload popmoney_account_payload = 20; } map exclude_from_json_data = 15; } @@ -961,6 +962,11 @@ message VenmoAccountPayload { string holder_name = 2; } +message PopmoneyAccountPayload { + string account_id = 1; + string holder_name = 2; +} + message PerfectMoneyAccountPayload { string account_nr = 1; } diff --git a/common/src/main/resources/i18n/displayStrings.properties b/common/src/main/resources/i18n/displayStrings.properties index e2feb53426a..fcca8054203 100644 --- a/common/src/main/resources/i18n/displayStrings.properties +++ b/common/src/main/resources/i18n/displayStrings.properties @@ -1626,6 +1626,7 @@ payment.uphold.accountId=Username or email or phone no.: payment.cashApp.cashTag=$Cashtag: payment.moneyBeam.accountId=Email or phone no.: payment.venmo.venmoUserName=Venmo username: +payment.popmoney.accountId=Email or phone no.: payment.supported.okpay=Supported currencies: payment.supported.uphold=Supported currencies: payment.limitations=Limitations: @@ -1672,6 +1673,7 @@ before starting a trade or creating an offer.\n\n\ \t● FirstBank Person to Person Transfers\n\ \t● Frost Send Money\n\ \t● U.S. Bank Send Money\n\ +\t● TD Bank\n\ \t● Wells Fargo SurePay\n\n\ 3. You need to be sure to not exceed the daily or monthly Zelle (ClearXchange) transfer limits.\n\n\ Please use Zelle (ClearXchange) only if you fulfill all those requirements, \ @@ -1714,6 +1716,7 @@ UPHOLD=Uphold CASH_APP=Cash App MONEY_BEAM=MoneyBeam VENMO=Venmo +POPMONEY=Popmoney PERFECT_MONEY=Perfect Money ALI_PAY=AliPay SEPA=SEPA @@ -1736,6 +1739,8 @@ MONEY_BEAM_SHORT=MoneyBeam # suppress inspection "UnusedProperty" VENMO_SHORT=Venmo # suppress inspection "UnusedProperty" +POPMONEY_SHORT=Popmoney +# suppress inspection "UnusedProperty" PERFECT_MONEY_SHORT=Perfect Money # suppress inspection "UnusedProperty" ALI_PAY_SHORT=AliPay diff --git a/core/src/main/java/io/bisq/core/payment/PaymentAccountFactory.java b/core/src/main/java/io/bisq/core/payment/PaymentAccountFactory.java index 59248a753c6..2832561e3c7 100644 --- a/core/src/main/java/io/bisq/core/payment/PaymentAccountFactory.java +++ b/core/src/main/java/io/bisq/core/payment/PaymentAccountFactory.java @@ -32,6 +32,8 @@ public static PaymentAccount getPaymentAccount(PaymentMethod paymentMethod) { return new MoneyBeamAccount(); case PaymentMethod.VENMO_ID: return new VenmoAccount(); + case PaymentMethod.POPMONEY_ID: + return new PopmoneyAccount(); case PaymentMethod.PERFECT_MONEY_ID: return new PerfectMoneyAccount(); case PaymentMethod.SEPA_ID: diff --git a/core/src/main/java/io/bisq/core/payment/PopmoneyAccount.java b/core/src/main/java/io/bisq/core/payment/PopmoneyAccount.java new file mode 100644 index 00000000000..00c03b7e5f7 --- /dev/null +++ b/core/src/main/java/io/bisq/core/payment/PopmoneyAccount.java @@ -0,0 +1,54 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package io.bisq.core.payment; + +import io.bisq.common.locale.FiatCurrency; +import io.bisq.core.payment.payload.PaymentAccountPayload; +import io.bisq.core.payment.payload.PaymentMethod; +import io.bisq.core.payment.payload.PopmoneyAccountPayload; +import lombok.EqualsAndHashCode; + +//TODO missing support for selected trade currency +@EqualsAndHashCode(callSuper = true) +public final class PopmoneyAccount extends PaymentAccount { + public PopmoneyAccount() { + super(PaymentMethod.POPMONEY); + setSingleTradeCurrency(new FiatCurrency("USD")); + } + + @Override + protected PaymentAccountPayload createPayload() { + return new PopmoneyAccountPayload(paymentMethod.getId(), id); + } + + public void setAccountId(String accountId) { + ((PopmoneyAccountPayload) paymentAccountPayload).setAccountId(accountId); + } + + public String getAccountId() { + return ((PopmoneyAccountPayload) paymentAccountPayload).getAccountId(); + } + + public void setHolderName(String holderName) { + ((PopmoneyAccountPayload) paymentAccountPayload).setHolderName(holderName); + } + + public String getHolderName() { + return ((PopmoneyAccountPayload) paymentAccountPayload).getHolderName(); + } +} diff --git a/core/src/main/java/io/bisq/core/payment/payload/PaymentMethod.java b/core/src/main/java/io/bisq/core/payment/payload/PaymentMethod.java index d0ba4f3f8e4..faa8d492eb2 100644 --- a/core/src/main/java/io/bisq/core/payment/payload/PaymentMethod.java +++ b/core/src/main/java/io/bisq/core/payment/payload/PaymentMethod.java @@ -51,6 +51,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable { public static final String CASH_APP_ID = "CASH_APP"; public static final String MONEY_BEAM_ID = "MONEY_BEAM"; public static final String VENMO_ID = "VENMO"; + public static final String POPMONEY_ID = "POPMONEY"; public static final String PERFECT_MONEY_ID = "PERFECT_MONEY"; public static final String SEPA_ID = "SEPA"; public static final String SEPA_INSTANT_ID = "SEPA_INSTANT"; @@ -73,6 +74,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable { public static PaymentMethod CASH_APP; public static PaymentMethod MONEY_BEAM; public static PaymentMethod VENMO; + public static PaymentMethod POPMONEY; public static PaymentMethod PERFECT_MONEY; public static PaymentMethod SEPA; public static PaymentMethod SEPA_INSTANT; @@ -179,6 +181,7 @@ public static List getAllValues() { CLEAR_X_CHANGE = new PaymentMethod(CLEAR_X_CHANGE_ID, 4 * DAY, maxTradeLimitMidRisk), CASH_APP = new PaymentMethod(CASH_APP_ID, DAY, maxTradeLimitMidRisk), VENMO = new PaymentMethod(VENMO_ID, DAY, maxTradeLimitMidRisk), + POPMONEY = new PaymentMethod(POPMONEY_ID, DAY, maxTradeLimitMidRisk), CHASE_QUICK_PAY = new PaymentMethod(CHASE_QUICK_PAY_ID, DAY, maxTradeLimitMidRisk), US_POSTAL_MONEY_ORDER = new PaymentMethod(US_POSTAL_MONEY_ORDER_ID, 8 * DAY, maxTradeLimitMidRisk), diff --git a/core/src/main/java/io/bisq/core/payment/payload/PopmoneyAccountPayload.java b/core/src/main/java/io/bisq/core/payment/payload/PopmoneyAccountPayload.java new file mode 100644 index 00000000000..3e62f85074d --- /dev/null +++ b/core/src/main/java/io/bisq/core/payment/payload/PopmoneyAccountPayload.java @@ -0,0 +1,103 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package io.bisq.core.payment.payload; + +import com.google.protobuf.Message; +import io.bisq.generated.protobuffer.PB; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.CollectionUtils; + +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; + +@EqualsAndHashCode(callSuper = true) +@ToString +@Setter +@Getter +@Slf4j +public final class PopmoneyAccountPayload extends PaymentAccountPayload { + private String accountId = ""; + private String holderName = ""; + + public PopmoneyAccountPayload(String paymentMethod, String id) { + super(paymentMethod, id); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // PROTO BUFFER + /////////////////////////////////////////////////////////////////////////////////////////// + + private PopmoneyAccountPayload(String paymentMethod, + String id, + String accountId, + String holderName, + long maxTradePeriod, + Map excludeFromJsonDataMap) { + super(paymentMethod, + id, + maxTradePeriod, + excludeFromJsonDataMap); + + this.accountId = accountId; + this.holderName = holderName; + } + + @Override + public Message toProtoMessage() { + return getPaymentAccountPayloadBuilder() + .setPopmoneyAccountPayload(PB.PopmoneyAccountPayload.newBuilder() + .setAccountId(accountId) + .setHolderName(holderName)) + .build(); + } + + public static PopmoneyAccountPayload fromProto(PB.PaymentAccountPayload proto) { + return new PopmoneyAccountPayload(proto.getPaymentMethodId(), + proto.getId(), + proto.getPopmoneyAccountPayload().getAccountId(), + proto.getPopmoneyAccountPayload().getHolderName(), + proto.getMaxTradePeriod(), + CollectionUtils.isEmpty(proto.getExcludeFromJsonDataMap()) ? null : new HashMap<>(proto.getExcludeFromJsonDataMap())); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public String getPaymentDetails() { + return "Popmoney - Holder name: " + holderName + ", email or phone no.: " + accountId; + } + + @Override + public String getPaymentDetailsForTradePopup() { + return getPaymentDetails(); + } + + @Override + public byte[] getAgeWitnessInputData() { + return super.getAgeWitnessInputData(accountId.getBytes(Charset.forName("UTF-8"))); + } +} diff --git a/core/src/main/java/io/bisq/core/payment/payload/VenmoAccountPayload.java b/core/src/main/java/io/bisq/core/payment/payload/VenmoAccountPayload.java index a240325d8cc..a49488769eb 100644 --- a/core/src/main/java/io/bisq/core/payment/payload/VenmoAccountPayload.java +++ b/core/src/main/java/io/bisq/core/payment/payload/VenmoAccountPayload.java @@ -88,7 +88,7 @@ public static VenmoAccountPayload fromProto(PB.PaymentAccountPayload proto) { @Override public String getPaymentDetails() { - return "Venmo - Account: " + venmoUserName; + return "Venmo - Holder name: " + holderName + ", Venmo username: " + venmoUserName; } @Override diff --git a/core/src/main/java/io/bisq/core/proto/CoreProtoResolver.java b/core/src/main/java/io/bisq/core/proto/CoreProtoResolver.java index dea5307fd52..66de17729f0 100644 --- a/core/src/main/java/io/bisq/core/proto/CoreProtoResolver.java +++ b/core/src/main/java/io/bisq/core/proto/CoreProtoResolver.java @@ -68,6 +68,8 @@ public PaymentAccountPayload fromProto(PB.PaymentAccountPayload proto) { return MoneyBeamAccountPayload.fromProto(proto); case VENMO_ACCOUNT_PAYLOAD: return VenmoAccountPayload.fromProto(proto); + case POPMONEY_ACCOUNT_PAYLOAD: + return PopmoneyAccountPayload.fromProto(proto); case PERFECT_MONEY_ACCOUNT_PAYLOAD: return PerfectMoneyAccountPayload.fromProto(proto); case SWISH_ACCOUNT_PAYLOAD: diff --git a/gui/src/main/java/io/bisq/gui/components/paymentmethods/PopmoneyForm.java b/gui/src/main/java/io/bisq/gui/components/paymentmethods/PopmoneyForm.java new file mode 100644 index 00000000000..47867e6c139 --- /dev/null +++ b/gui/src/main/java/io/bisq/gui/components/paymentmethods/PopmoneyForm.java @@ -0,0 +1,114 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package io.bisq.gui.components.paymentmethods; + +import io.bisq.common.locale.Res; +import io.bisq.common.locale.TradeCurrency; +import io.bisq.core.payment.AccountAgeWitnessService; +import io.bisq.core.payment.PaymentAccount; +import io.bisq.core.payment.PopmoneyAccount; +import io.bisq.core.payment.payload.PaymentAccountPayload; +import io.bisq.core.payment.payload.PopmoneyAccountPayload; +import io.bisq.gui.components.InputTextField; +import io.bisq.gui.util.BSFormatter; +import io.bisq.gui.util.Layout; +import io.bisq.gui.util.validation.InputValidator; +import io.bisq.gui.util.validation.PopmoneyValidator; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import org.apache.commons.lang3.StringUtils; + +import static io.bisq.gui.util.FormBuilder.*; + +public class PopmoneyForm extends PaymentMethodForm { + private final PopmoneyAccount account; + private final PopmoneyValidator validator; + private InputTextField accountIdInputTextField; + + public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccountPayload paymentAccountPayload) { + addLabelTextField(gridPane, ++gridRow, Res.getWithCol("payment.account.owner"), + ((PopmoneyAccountPayload) paymentAccountPayload).getHolderName()); + addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.get("payment.popmoney.accountId"), ((PopmoneyAccountPayload) paymentAccountPayload).getAccountId()); + return gridRow; + } + + public PopmoneyForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, PopmoneyValidator aliPayValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) { + super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter); + this.account = (PopmoneyAccount) paymentAccount; + this.validator = aliPayValidator; + } + + @Override + public void addFormForAddAccount() { + gridRowFrom = gridRow + 1; + + InputTextField holderNameInputTextField = addLabelInputTextField(gridPane, ++gridRow, + Res.getWithCol("payment.account.owner")).second; + holderNameInputTextField.setValidator(inputValidator); + holderNameInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + account.setHolderName(newValue); + updateFromInputs(); + }); + + accountIdInputTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("payment.popmoney.accountId")).second; + accountIdInputTextField.setValidator(validator); + accountIdInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + account.setAccountId(newValue); + updateFromInputs(); + }); + + final TradeCurrency singleTradeCurrency = account.getSingleTradeCurrency(); + final String nameAndCode = singleTradeCurrency != null ? singleTradeCurrency.getNameAndCode() : ""; + addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.currency"), nameAndCode); + addLimitations(); + addAccountNameTextFieldWithAutoFillCheckBox(); + } + + @Override + protected void autoFillNameTextField() { + if (useCustomAccountNameCheckBox != null && !useCustomAccountNameCheckBox.isSelected()) { + String accountNr = accountIdInputTextField.getText(); + accountNr = StringUtils.abbreviate(accountNr, 9); + String method = Res.get(paymentAccount.getPaymentMethod().getId()); + accountNameTextField.setText(method.concat(": ").concat(accountNr)); + } + } + + @Override + public void addFormForDisplayAccount() { + gridRowFrom = gridRow; + addLabelTextField(gridPane, gridRow, Res.get("payment.account.name"), account.getAccountName(), Layout.FIRST_ROW_AND_GROUP_DISTANCE); + addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.paymentMethod"), Res.get(account.getPaymentMethod().getId())); + addLabelTextField(gridPane, ++gridRow, Res.getWithCol("payment.account.owner"), + account.getHolderName()); + TextField field = addLabelTextField(gridPane, ++gridRow, Res.get("payment.popmoney.accountId"), account.getAccountId()).second; + field.setMouseTransparent(false); + final TradeCurrency singleTradeCurrency = account.getSingleTradeCurrency(); + final String nameAndCode = singleTradeCurrency != null ? singleTradeCurrency.getNameAndCode() : ""; + addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.currency"), nameAndCode); + addLimitations(); + } + + @Override + public void updateAllInputsValid() { + allInputsValid.set(isAccountNameValid() + && inputValidator.validate(account.getHolderName()).isValid + && validator.validate(account.getAccountId()).isValid + && account.getTradeCurrencies().size() > 0); + } +} diff --git a/gui/src/main/java/io/bisq/gui/main/account/content/fiataccounts/FiatAccountsView.java b/gui/src/main/java/io/bisq/gui/main/account/content/fiataccounts/FiatAccountsView.java index f715726118b..7c905d38317 100644 --- a/gui/src/main/java/io/bisq/gui/main/account/content/fiataccounts/FiatAccountsView.java +++ b/gui/src/main/java/io/bisq/gui/main/account/content/fiataccounts/FiatAccountsView.java @@ -66,6 +66,7 @@ public class FiatAccountsView extends ActivatableViewAndModel. + */ + +package io.bisq.gui.util.validation; + + +public final class PopmoneyValidator extends InputValidator { + + @Override + public ValidationResult validate(String input) { + // TODO + return super.validate(input); + } +}