Skip to content

Commit

Permalink
add Nequi payment method
Browse files Browse the repository at this point in the history
Signed-off-by: jmacxx <[email protected]>
  • Loading branch information
jmacxx committed Sep 28, 2021
1 parent 9e5a1c2 commit f792db9
Show file tree
Hide file tree
Showing 11 changed files with 303 additions and 1 deletion.
56 changes: 56 additions & 0 deletions core/src/main/java/bisq/core/payment/NequiAccount.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/

package bisq.core.payment;

import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.payment.payload.NequiAccountPayload;

import lombok.EqualsAndHashCode;

@EqualsAndHashCode(callSuper = true)
public final class NequiAccount extends CountryBasedPaymentAccount {
public NequiAccount() {
super(PaymentMethod.NEQUI);
}

@Override
protected PaymentAccountPayload createPayload() {
return new NequiAccountPayload(paymentMethod.getId(), id);
}

public void setMobileNr(String mobileNr) {
((NequiAccountPayload) paymentAccountPayload).setMobileNr(mobileNr);
}

public String getMobileNr() {
return ((NequiAccountPayload) paymentAccountPayload).getMobileNr();
}

public String getMessageForBuyer() {
return "payment.nequi.info.buyer";
}

public String getMessageForSeller() {
return "payment.nequi.info.seller";
}

public String getMessageForAccountCreation() {
return "payment.nequi.info.account";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ public static PaymentAccount getPaymentAccount(PaymentMethod paymentMethod) {
return new UpiAccount();
case PaymentMethod.PAYTM_ID:
return new PaytmAccount();
case PaymentMethod.NEQUI_ID:
return new NequiAccount();
case PaymentMethod.AMAZON_GIFT_CARD_ID:
return new AmazonGiftCardAccount();
case PaymentMethod.BLOCK_CHAINS_INSTANT_ID:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/

package bisq.core.payment.payload;

import bisq.core.locale.Res;

import com.google.protobuf.Message;

import java.nio.charset.StandardCharsets;

import java.util.HashMap;
import java.util.Map;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;

@EqualsAndHashCode(callSuper = true)
@ToString
@Setter
@Getter
@Slf4j
public final class NequiAccountPayload extends CountryBasedPaymentAccountPayload {
private String mobileNr = "";

public NequiAccountPayload(String paymentMethod, String id) {
super(paymentMethod, id);
}

private NequiAccountPayload(String paymentMethod,
String id,
String countryCode,
String mobileNr,
long maxTradePeriod,
Map<String, String> excludeFromJsonDataMap) {
super(paymentMethod,
id,
countryCode,
maxTradePeriod,
excludeFromJsonDataMap);

this.mobileNr = mobileNr;
}

@Override
public Message toProtoMessage() {
protobuf.NequiAccountPayload.Builder builder = protobuf.NequiAccountPayload.newBuilder()
.setMobileNr(mobileNr);
final protobuf.CountryBasedPaymentAccountPayload.Builder countryBasedPaymentAccountPayload = getPaymentAccountPayloadBuilder()
.getCountryBasedPaymentAccountPayloadBuilder()
.setNequiAccountPayload(builder);
return getPaymentAccountPayloadBuilder()
.setCountryBasedPaymentAccountPayload(countryBasedPaymentAccountPayload)
.build();
}

public static NequiAccountPayload fromProto(protobuf.PaymentAccountPayload proto) {
protobuf.CountryBasedPaymentAccountPayload countryBasedPaymentAccountPayload = proto.getCountryBasedPaymentAccountPayload();
protobuf.NequiAccountPayload paytmAccountPayloadPB = countryBasedPaymentAccountPayload.getNequiAccountPayload();
return new NequiAccountPayload(proto.getPaymentMethodId(),
proto.getId(),
countryBasedPaymentAccountPayload.getCountryCode(),
paytmAccountPayloadPB.getMobileNr(),
proto.getMaxTradePeriod(),
new HashMap<>(proto.getExcludeFromJsonDataMap()));
}

@Override
public String getPaymentDetails() {
return Res.get(paymentMethodId) + " - " + Res.getWithCol("payment.mobile") + " " + mobileNr;
}

@Override
public String getPaymentDetailsForTradePopup() {
return getPaymentDetails();
}

@Override
public byte[] getAgeWitnessInputData() {
return super.getAgeWitnessInputData(mobileNr.getBytes(StandardCharsets.UTF_8));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
public static final String IMPS_ID = "IMPS";
public static final String UPI_ID = "UPI";
public static final String PAYTM_ID = "PAYTM";
public static final String NEQUI_ID = "NEQUI";
public static final String AMAZON_GIFT_CARD_ID = "AMAZON_GIFT_CARD";
public static final String BLOCK_CHAINS_INSTANT_ID = "BLOCK_CHAINS_INSTANT";
public static final String CASH_BY_MAIL_ID = "CASH_BY_MAIL";
Expand Down Expand Up @@ -154,6 +155,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
public static PaymentMethod IMPS;
public static PaymentMethod UPI;
public static PaymentMethod PAYTM;
public static PaymentMethod NEQUI;
public static PaymentMethod AMAZON_GIFT_CARD;
public static PaymentMethod BLOCK_CHAINS_INSTANT;
public static PaymentMethod CASH_BY_MAIL;
Expand Down Expand Up @@ -218,6 +220,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
IMPS = new PaymentMethod(IMPS_ID, DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK),
UPI = new PaymentMethod(UPI_ID, DAY, Coin.parseCoin("0.05")),
PAYTM = new PaymentMethod(PAYTM_ID, DAY, Coin.parseCoin("0.05")),
NEQUI = new PaymentMethod(NEQUI_ID, DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK),
CAPITUAL = new PaymentMethod(CAPITUAL_ID, DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK),
CELPAY = new PaymentMethod(CELPAY_ID, DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK),
SWIFT = new PaymentMethod(SWIFT_ID, 7 * DAY, DEFAULT_TRADE_LIMIT_MID_RISK),
Expand Down
3 changes: 3 additions & 0 deletions core/src/main/java/bisq/core/proto/CoreProtoResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import bisq.core.payment.payload.MoneyGramAccountPayload;
import bisq.core.payment.payload.NationalBankAccountPayload;
import bisq.core.payment.payload.NeftAccountPayload;
import bisq.core.payment.payload.NequiAccountPayload;
import bisq.core.payment.payload.OKPayAccountPayload;
import bisq.core.payment.payload.PaxumAccountPayload;
import bisq.core.payment.payload.PaymentAccountPayload;
Expand Down Expand Up @@ -128,6 +129,8 @@ public PaymentAccountPayload fromProto(protobuf.PaymentAccountPayload proto) {
return UpiAccountPayload.fromProto(proto);
case PAYTM_ACCOUNT_PAYLOAD:
return PaytmAccountPayload.fromProto(proto);
case NEQUI_ACCOUNT_PAYLOAD:
return NequiAccountPayload.fromProto(proto);
case IFSC_BASED_ACCOUNT_PAYLOAD:
final protobuf.IfscBasedAccountPayload.MessageCase messageCaseIfsc = proto.getCountryBasedPaymentAccountPayload().getIfscBasedAccountPayload().getMessageCase();
switch (messageCaseIfsc) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ private enum PaymentMethodMapper {
IMPS,
UPI,
PAYTM,
CELPAY
CELPAY,
NEQUI
}

@Getter
Expand Down
20 changes: 20 additions & 0 deletions core/src/main/resources/i18n/displayStrings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3614,6 +3614,22 @@ CelPay supports multiple stablecoins:\n\n\
BTC Sellers should expect to receive any matching currency stablecoin from the BTC Buyer. It is possible for the BTC Buyer to send any matching currency stablecoin.
payment.celpay.supportedCurrenciesForReceiver=Supported currencies (please note: all the currencies below are supported stable coins within the Celcius app. Trades are for stable coins, not fiat.)

payment.nequi.info.account=Please make sure to include your phone number that is associated with your Nequi account.\n\n\
When users set up a Nequi account payment limits are set to a maximum of ~ 7,000,000 COP that can be sent per month.\n\n\
If you intend to trade amount of over 7,000,000 COP per trade you will need to complete KYC with Bancolombia and pay a fee \
of around 15,000 COP. After this all transactions will incur a 0.4% of tax. Please ensure you are aware of the latest taxes.\n\n\
Users should also be aware of account limits. Trades above Nequi account limits will likely have to be cancelled.
payment.nequi.info.buyer=Please send payment only to the phone number provided in the BTC Seller's Bisq account.\n\n\
When users set up a Nequi account, payment limits are set to a maximum of ~ 7,000,000 COP that can be sent per month.\n\n\
If you intend to trade amount of over 7,000,000 COP per trade you will need to complete KYC with Bancolombia and pay a fee \
of around 15,000 COP. After this all transactions will incur a 0.4% of tax. Please ensure you are aware of the latest taxes.\n\n\
Users should also be aware of account limits. Trades above Nequi account limits will likely have to be cancelled.
payment.nequi.info.seller=Please check that the payment received matches the phone number provided in the BTC Buyer's Bisq account.\n\n\
When users set up a Nequi account, payment limits are set to a maximum of ~ 7,000,000 COP that can be sent per month.\n\n\
If you intend to trade amount of over 7,000,000 COP per trade you will need to complete KYC with Bancolombia and pay a fee \
of around 15,000 COP. After this all transactions will incur a 0.4% of tax. Please ensure you are aware of the latest taxes.\n\n\
Users should also be aware of account limits. Trades above Nequi account limits will likely have to be cancelled.

payment.usPostalMoneyOrder.info=Trading using US Postal Money Orders (USPMO) on Bisq requires that you understand the following:\n\
\n\
- BTC buyers must write the BTC Seller’s name in both the Payer and the Payee’s fields & take a high-resolution photo of the USPMO and envelope with proof of tracking before sending.\n\
Expand Down Expand Up @@ -3791,6 +3807,8 @@ UPI=India/UPI
# suppress inspection "UnusedProperty"
PAYTM=India/PayTM
# suppress inspection "UnusedProperty"
NEQUI=Nequi
# suppress inspection "UnusedProperty"
AMAZON_GIFT_CARD=Amazon eGift Card
# suppress inspection "UnusedProperty"
BLOCK_CHAINS_INSTANT=Altcoins Instant
Expand Down Expand Up @@ -3863,6 +3881,8 @@ UPI_SHORT=UPI
# suppress inspection "UnusedProperty"
PAYTM_SHORT=PayTM
# suppress inspection "UnusedProperty"
NEQUI_SHORT=Nequi
# suppress inspection "UnusedProperty"
AMAZON_GIFT_CARD_SHORT=Amazon eGift Card
# suppress inspection "UnusedProperty"
BLOCK_CHAINS_INSTANT_SHORT=Altcoins Instant
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/

package bisq.desktop.components.paymentmethods;

import bisq.desktop.components.InputTextField;
import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;

import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.CountryUtil;
import bisq.core.locale.FiatCurrency;
import bisq.core.locale.Res;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.NequiAccount;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.payment.payload.NequiAccountPayload;
import bisq.core.util.coin.CoinFormatter;
import bisq.core.util.validation.InputValidator;

import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;

import static bisq.desktop.util.FormBuilder.addCompactTopLabelTextField;
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
import static bisq.desktop.util.FormBuilder.addTopLabelTextFieldWithCopyIcon;

public class NequiForm extends PaymentMethodForm {
private final NequiAccount account;
private InputTextField mobileNrInputTextField;

public static int addFormForBuyer(GridPane gridPane, int gridRow,
PaymentAccountPayload paymentAccountPayload) {
addTopLabelTextFieldWithCopyIcon(gridPane, gridRow, 1, Res.get("payment.mobile"),
((NequiAccountPayload) paymentAccountPayload).getMobileNr(), Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE);
return gridRow;
}

public NequiForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService,
InputValidator inputValidator, GridPane gridPane,
int gridRow, CoinFormatter formatter) {
super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter);
this.account = (NequiAccount) paymentAccount;
}

@Override
public void addFormForAddAccount() {
// this payment method is only for Columbia/COP
account.setSingleTradeCurrency(new FiatCurrency("COP"));
CountryUtil.findCountryByCode("CO").ifPresent(c -> account.setCountry(c));

gridRowFrom = gridRow + 1;

mobileNrInputTextField = FormBuilder.addInputTextField(gridPane, ++gridRow, Res.get("payment.mobile"));
mobileNrInputTextField.setValidator(inputValidator);
mobileNrInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
account.setMobileNr(newValue.trim());
updateFromInputs();
});

addTopLabelTextField(gridPane, ++gridRow, Res.get("shared.currency"), account.getSingleTradeCurrency().getNameAndCode());
addTopLabelTextField(gridPane, ++gridRow, Res.get("shared.country"), account.getCountry().name);
addLimitations(false);
addAccountNameTextFieldWithAutoFillToggleButton();
}

@Override
protected void autoFillNameTextField() {
setAccountNameWithString(mobileNrInputTextField.getText());
}

@Override
public void addFormForDisplayAccount() {
gridRowFrom = gridRow;
addTopLabelTextField(gridPane, gridRow, Res.get("payment.account.name"),
account.getAccountName(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("shared.paymentMethod"),
Res.get(account.getPaymentMethod().getId()));
TextField field = addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.mobile"),
account.getMobileNr()).second;
field.setMouseTransparent(false);
addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("shared.currency"), account.getSingleTradeCurrency().getNameAndCode());
addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("shared.country"), account.getCountry().name);
addLimitations(true);
}

@Override
public void updateAllInputsValid() {
allInputsValid.set(isAccountNameValid()
&& inputValidator.validate(account.getMobileNr()).isValid);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import bisq.desktop.components.paymentmethods.MoneyGramForm;
import bisq.desktop.components.paymentmethods.NationalBankForm;
import bisq.desktop.components.paymentmethods.NeftForm;
import bisq.desktop.components.paymentmethods.NequiForm;
import bisq.desktop.components.paymentmethods.PaymentMethodForm;
import bisq.desktop.components.paymentmethods.PaytmForm;
import bisq.desktop.components.paymentmethods.PerfectMoneyForm;
Expand Down Expand Up @@ -562,6 +563,8 @@ private PaymentMethodForm getPaymentMethodForm(PaymentMethod paymentMethod, Paym
return new UpiForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
case PaymentMethod.PAYTM_ID:
return new PaytmForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
case PaymentMethod.NEQUI_ID:
return new NequiForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
case PaymentMethod.AMAZON_GIFT_CARD_ID:
return new AmazonGiftCardForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
case PaymentMethod.CAPITUAL_ID:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import bisq.desktop.components.paymentmethods.MoneyGramForm;
import bisq.desktop.components.paymentmethods.NationalBankForm;
import bisq.desktop.components.paymentmethods.NeftForm;
import bisq.desktop.components.paymentmethods.NequiForm;
import bisq.desktop.components.paymentmethods.PaxumForm;
import bisq.desktop.components.paymentmethods.PayseraForm;
import bisq.desktop.components.paymentmethods.PaytmForm;
Expand Down Expand Up @@ -352,6 +353,9 @@ protected void addContent() {
case PaymentMethod.PAYTM_ID:
gridRow = PaytmForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload);
break;
case PaymentMethod.NEQUI_ID:
gridRow = NequiForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload);
break;
case PaymentMethod.AMAZON_GIFT_CARD_ID:
gridRow = AmazonGiftCardForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload);
break;
Expand Down
Loading

0 comments on commit f792db9

Please sign in to comment.