diff --git a/assets/css/admin.css b/assets/css/admin.css index 7b6d75945de..310fc919541 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -135,6 +135,10 @@ background-image: url( '../images/payment-methods/klarna.svg' ); } +.payment-method__brand--multibanco { + background-image: url( '../images/payment-methods/klarna.svg' ); // TODO: Replace with Multibanco icon. +} + .wc_gateways tr[data-gateway_id='woocommerce_payments'] .payment-method__icon { border: 1px solid #ddd; border-radius: 2px; diff --git a/client/additional-methods-setup/constants.js b/client/additional-methods-setup/constants.js index b189fc86459..9274ca96dd8 100644 --- a/client/additional-methods-setup/constants.js +++ b/client/additional-methods-setup/constants.js @@ -11,6 +11,7 @@ export const upeMethods = [ 'afterpay_clearpay', 'jcb', 'klarna', + 'multibanco', ]; export const upeCapabilityStatuses = { diff --git a/client/checkout/blocks/index.js b/client/checkout/blocks/index.js index 3f98863d707..8b7269b4001 100644 --- a/client/checkout/blocks/index.js +++ b/client/checkout/blocks/index.js @@ -40,6 +40,7 @@ import { PAYMENT_METHOD_NAME_AFFIRM, PAYMENT_METHOD_NAME_AFTERPAY, PAYMENT_METHOD_NAME_KLARNA, + PAYMENT_METHOD_NAME_MULTIBANCO, } from '../constants.js'; import { getDeferredIntentCreationUPEFields } from './payment-elements'; import { handleWooPayEmailInput } from '../woopay/email-input-iframe'; @@ -61,6 +62,7 @@ const upeMethods = { affirm: PAYMENT_METHOD_NAME_AFFIRM, afterpay_clearpay: PAYMENT_METHOD_NAME_AFTERPAY, klarna: PAYMENT_METHOD_NAME_KLARNA, + multibanco: PAYMENT_METHOD_NAME_MULTIBANCO, }; const enabledPaymentMethodsConfig = getUPEConfig( 'paymentMethodsConfig' ); diff --git a/client/checkout/constants.js b/client/checkout/constants.js index 1c9b616fe58..68d4fc34244 100644 --- a/client/checkout/constants.js +++ b/client/checkout/constants.js @@ -11,6 +11,7 @@ export const PAYMENT_METHOD_NAME_AFFIRM = 'woocommerce_payments_affirm'; export const PAYMENT_METHOD_NAME_AFTERPAY = 'woocommerce_payments_afterpay_clearpay'; export const PAYMENT_METHOD_NAME_KLARNA = 'woocommerce_payments_klarna'; +export const PAYMENT_METHOD_NAME_MULTIBANCO = 'woocommerce_payments_multibanco'; export const PAYMENT_METHOD_NAME_EXPRESS_CHECKOUT_ELEMENT = 'woocommerce_payments_express_checkout'; export const PAYMENT_METHOD_NAME_WOOPAY_EXPRESS_CHECKOUT = @@ -32,6 +33,7 @@ export function getPaymentMethodsConstants() { PAYMENT_METHOD_NAME_AFTERPAY, PAYMENT_METHOD_NAME_CARD, PAYMENT_METHOD_NAME_KLARNA, + PAYMENT_METHOD_NAME_MULTIBANCO, ]; } diff --git a/client/components/payment-method-details/index.js b/client/components/payment-method-details/index.js index dab608ea867..5b9c7784b66 100755 --- a/client/components/payment-method-details/index.js +++ b/client/components/payment-method-details/index.js @@ -46,6 +46,7 @@ const formatDetails = ( payment ) => { case 'affirm': case 'afterpay_clearpay': case 'klarna': + case 'multibanco': default: return ; } diff --git a/client/constants/payment-method.ts b/client/constants/payment-method.ts index 4ca2b2d7dc4..e99c4ece223 100644 --- a/client/constants/payment-method.ts +++ b/client/constants/payment-method.ts @@ -12,6 +12,7 @@ enum PAYMENT_METHOD_IDS { CARD_PRESENT = 'card_present', EPS = 'eps', KLARNA = 'klarna', + MULTIBANCO = 'multibanco', GIROPAY = 'giropay', IDEAL = 'ideal', LINK = 'link', diff --git a/client/payment-details/payment-method/index.js b/client/payment-details/payment-method/index.js index 984ab87772b..e8ff443c785 100644 --- a/client/payment-details/payment-method/index.js +++ b/client/payment-details/payment-method/index.js @@ -20,6 +20,7 @@ import EpsDetails from './eps'; import GiropayDetails from './giropay'; import IdealDetails from './ideal'; import KlarnaDetails from './klarna'; +import MultibancoDetails from './multibanco'; import P24Details from './p24'; import SepaDetails from './sepa'; import SofortDetails from './sofort'; @@ -35,6 +36,7 @@ const detailsComponentMap = { giropay: GiropayDetails, ideal: IdealDetails, klarna: KlarnaDetails, + multibanco: MultibancoDetails, p24: P24Details, sepa_debit: SepaDetails, sofort: SofortDetails, diff --git a/client/payment-details/payment-method/multibanco/index.js b/client/payment-details/payment-method/multibanco/index.js new file mode 100644 index 00000000000..d271bdc90e3 --- /dev/null +++ b/client/payment-details/payment-method/multibanco/index.js @@ -0,0 +1,131 @@ +/** @format **/ + +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies. + */ +import Detail from '../detail'; + +/** + * Extracts and formats payment method details from a charge. + * + * @param {Object} charge The charge object. + * @return {Object} A flat hash of all necessary values. + */ +const formatPaymentMethodDetails = ( charge ) => { + const { billing_details: billingDetails, payment_method: id } = charge; + + const { + payment_method_category: paymentMethodCategory, + preferred_locale: preferredLocale, + } = charge.payment_method_details.multibanco; + + const paymentMethodCategoryTranslations = { + pay_later: __( 'pay_later', 'woocommerce-payments' ), + pay_now: __( 'pay_now', 'woocommerce-payments' ), + pay_with_financing: __( 'pay_with_financing', 'woocommerce-payments' ), + pay_in_installments: __( + 'pay_in_installments', + 'woocommerce-payments' + ), + }; + + const { name, email, formatted_address: formattedAddress } = billingDetails; + + return { + id, + name, + email, + formattedAddress, + paymentMethodCategory: + paymentMethodCategoryTranslations[ paymentMethodCategory ], + preferredLocale, + }; +}; + +/** + * Placeholders to display while loading. + */ +const paymentMethodPlaceholders = { + id: 'id placeholder', + name: 'name placeholder', + email: 'email placeholder', + formattedAddress: 'address placeholder', + paymentMethodCategory: 'category placeholder', + preferredLocale: 'locale placeholder', +}; + +const MultibancoDetails = ( { charge = {}, isLoading } ) => { + const details = charge.payment_method_details + ? formatPaymentMethodDetails( charge ) + : paymentMethodPlaceholders; + + const { + id, + name, + email, + formattedAddress, + paymentMethodCategory, + preferredLocale, + } = details; + + return ( +
+
+ + { id } + + + + { paymentMethodCategory } + + + + { preferredLocale } + +
+ +
+ + { name } + + + + { email } + + + + + +
+
+ ); +}; + +export default MultibancoDetails; diff --git a/client/payment-methods-map.tsx b/client/payment-methods-map.tsx index b22ca1f9ae2..08b6cedf6d8 100644 --- a/client/payment-methods-map.tsx +++ b/client/payment-methods-map.tsx @@ -233,6 +233,21 @@ const PaymentMethodInformationObject: Record< allows_pay_later: true, accepts_only_domestic_payment: true, }, + multibanco: { + // TODO: Update. + id: 'multibanco', + label: __( 'Multibanco', 'woocommerce-payments' ), + description: __( + 'Allow customers to pay over time or pay now with Klarna.', + 'woocommerce-payments' + ), + icon: KlarnaIcon, + currencies: [ 'EUR' ], + stripe_key: 'multibanco_payments', + allows_manual_capture: false, + allows_pay_later: true, + accepts_only_domestic_payment: false, + }, }; export default PaymentMethodInformationObject; diff --git a/includes/class-wc-payment-gateway-wcpay.php b/includes/class-wc-payment-gateway-wcpay.php index d1be21241b9..cff0e8eedf4 100644 --- a/includes/class-wc-payment-gateway-wcpay.php +++ b/includes/class-wc-payment-gateway-wcpay.php @@ -72,6 +72,7 @@ use WCPay\Payment_Methods\Giropay_Payment_Method; use WCPay\Payment_Methods\Ideal_Payment_Method; use WCPay\Payment_Methods\Klarna_Payment_Method; +use WCPay\Payment_Methods\Multibanco_Payment_Method; use WCPay\Payment_Methods\P24_Payment_Method; use WCPay\Payment_Methods\Sepa_Payment_Method; use WCPay\Payment_Methods\Sofort_Payment_Method; @@ -353,6 +354,7 @@ public function __construct( 'affirm' => 'affirm_payments', 'afterpay_clearpay' => 'afterpay_clearpay_payments', 'klarna' => 'klarna_payments', + 'multibanco' => 'multibanco_payments', 'jcb' => 'jcb_payments', ]; @@ -4083,6 +4085,7 @@ static function ( $method ) { } ); } + $enabled_payment_methods[] = 'multibanco'; return $enabled_payment_methods; } @@ -4121,6 +4124,7 @@ public function get_upe_available_payment_methods() { $available_methods[] = Affirm_Payment_Method::PAYMENT_METHOD_STRIPE_ID; $available_methods[] = Afterpay_Payment_Method::PAYMENT_METHOD_STRIPE_ID; $available_methods[] = Klarna_Payment_Method::PAYMENT_METHOD_STRIPE_ID; + $available_methods[] = Multibanco_Payment_Method::PAYMENT_METHOD_STRIPE_ID; $available_methods = array_values( apply_filters( diff --git a/includes/class-wc-payments.php b/includes/class-wc-payments.php index 4ad2d32625e..a19392aecf9 100644 --- a/includes/class-wc-payments.php +++ b/includes/class-wc-payments.php @@ -17,6 +17,7 @@ use WCPay\Payment_Methods\Becs_Payment_Method; use WCPay\Payment_Methods\Giropay_Payment_Method; use WCPay\Payment_Methods\Klarna_Payment_Method; +use WCPay\Payment_Methods\Multibanco_Payment_Method; use WCPay\Payment_Methods\P24_Payment_Method; use WCPay\Payment_Methods\Sepa_Payment_Method; use WCPay\Payment_Methods\Sofort_Payment_Method; @@ -436,6 +437,7 @@ public static function init() { include_once __DIR__ . '/payment-methods/class-affirm-payment-method.php'; include_once __DIR__ . '/payment-methods/class-afterpay-payment-method.php'; include_once __DIR__ . '/payment-methods/class-klarna-payment-method.php'; + include_once __DIR__ . '/payment-methods/class-multibanco-payment-method.php'; include_once __DIR__ . '/express-checkout/class-wc-payments-express-checkout-button-helper.php'; include_once __DIR__ . '/class-wc-payment-token-wcpay-sepa.php'; include_once __DIR__ . '/class-wc-payments-status.php'; @@ -572,6 +574,7 @@ public static function init() { Affirm_Payment_Method::class, Afterpay_Payment_Method::class, Klarna_Payment_Method::class, + Multibanco_Payment_Method::class, ]; $payment_methods = []; diff --git a/includes/constants/class-payment-method.php b/includes/constants/class-payment-method.php index ee498864ab5..64848372862 100644 --- a/includes/constants/class-payment-method.php +++ b/includes/constants/class-payment-method.php @@ -35,6 +35,7 @@ class Payment_Method extends Base_Constant { const AFFIRM = 'affirm'; const AFTERPAY = 'afterpay_clearpay'; const KLARNA = 'klarna'; + const MULTIBANCO = 'multibanco'; const IPP_ALLOWED_PAYMENT_METHODS = [ self::CARD_PRESENT, diff --git a/includes/payment-methods/class-multibanco-payment-method.php b/includes/payment-methods/class-multibanco-payment-method.php new file mode 100644 index 00000000000..108f2ccdae1 --- /dev/null +++ b/includes/payment-methods/class-multibanco-payment-method.php @@ -0,0 +1,63 @@ +stripe_id = self::PAYMENT_METHOD_STRIPE_ID; + $this->is_reusable = false; + $this->is_bnpl = true; + $this->icon_url = plugins_url( 'assets/images/payment-methods/klarna-pill.svg', WCPAY_PLUGIN_FILE ); + $this->currencies = [ Currency_Code::EURO ]; + $this->accept_only_domestic_payment = false; + + // https://stripe.com/en-br/resources/more/sepa-country-list#list-of-sepa-countries. + $eu_countries = [ Country_Code::AUSTRIA, Country_Code::BELGIUM, Country_Code::BULGARIA, Country_Code::CROATIA, Country_Code::CYPRUS, Country_Code::CZECHIA, Country_Code::DENMARK, Country_Code::ESTONIA, Country_Code::FINLAND, Country_Code::FRANCE, Country_Code::GERMANY, Country_Code::GREECE, Country_Code::HUNGARY, Country_Code::IRELAND, Country_Code::ITALY, Country_Code::LATVIA, Country_Code::LITHUANIA, Country_Code::LUXEMBOURG, Country_Code::MALTA, Country_Code::NETHERLANDS, Country_Code::POLAND, Country_Code::PORTUGAL, Country_Code::ROMANIA, Country_Code::SLOVAKIA, Country_Code::SLOVENIA, Country_Code::SPAIN, Country_Code::SWEDEN ]; + $additional_sepa_countries = [ Country_Code::SWITZERLAND, Country_Code::UNITED_KINGDOM, Country_Code::SAN_MARINO, Country_Code::VATICAN_CITY, Country_Code::ANDORRA, Country_Code::MONACO, Country_Code::LIECHTENSTEIN, Country_Code::NORWAY, Country_Code::ICELAND ]; + $this->countries = array_merge( $eu_countries, $additional_sepa_countries ); + } + + /** + * Returns payment method title + * + * @param string|null $account_country Country of merchants account. + * @param array|false $payment_details Optional payment details from charge object. + * + * @return string + */ + public function get_title( ?string $account_country = null, $payment_details = false ) { + return __( 'Multibanco', 'woocommerce-payments' ); + } + + /** + * Returns testing credentials to be printed at checkout in test mode. + * + * @param string $account_country The country of the account. + * @return string + */ + public function get_testing_instructions( string $account_country ) { + return ''; + } +}