├── .gitignore ├── Api ├── CommandManagerInterface.php ├── Data │ ├── QuoteAttemptInterface.php │ ├── QuoteInterface.php │ └── QuoteStatusInterface.php ├── Fallback │ └── AuthoriseInterface.php ├── Payment │ └── CommandManagerInterface.php ├── Profiling │ ├── Data │ │ ├── ItemInterface.php │ │ └── ItemSearchResultsInterface.php │ └── ItemRepositoryInterface.php ├── Quote │ ├── AttemptRepositoryInterface.php │ └── CancelFacadeInterface.php ├── QuoteManagementInterface.php ├── QuoteRepositoryInterface.php └── Transaction │ └── PaymentDetailsInterface.php ├── Block ├── Adminhtml │ ├── Order │ │ └── View │ │ │ └── Info │ │ │ └── PaymentInfo.php │ └── System │ │ └── Config │ │ ├── Fieldset │ │ ├── Hint.php │ │ └── Payment.php │ │ └── TestCredentials.php ├── Express │ └── Button.php ├── Form.php ├── Info.php ├── Monitoring │ ├── Buttons.php │ └── View.php ├── PartialVoid │ └── Order │ │ └── Email │ │ └── Items.php └── Profiling │ └── View.php ├── CONTRIBUTING.md ├── Controller ├── Adminhtml │ ├── Monitoring │ │ ├── Cancel.php │ │ ├── Index.php │ │ ├── Restart.php │ │ └── View.php │ ├── Profiling │ │ ├── Index.php │ │ ├── MassDelete.php │ │ └── View.php │ └── System │ │ └── Config │ │ └── TestCredentials.php └── Payment │ ├── Callback.php │ ├── ConsentRemoval.php │ ├── Fallback.php │ ├── InitExpress.php │ ├── InitRegular.php │ ├── Klarna │ └── InitRegular.php │ └── ShippingDetails.php ├── Cron ├── CancelQuoteByAttempts.php ├── ClearQuotesHistory.php └── FetchOrderFromVipps.php ├── Gateway ├── Command │ ├── CancelCommand.php │ ├── CaptureCommand.php │ ├── CommandManager.php │ ├── GatewayCommand.php │ ├── PaymentDetailsProvider.php │ ├── ReceiptSender.php │ └── RefundCommand.php ├── Config │ └── Config.php ├── Exception │ ├── AuthenticationException.php │ ├── CustomerException.php │ ├── ExceptionFactory.php │ ├── InvalidRequestException.php │ ├── MerchantException.php │ ├── PaymentException.php │ ├── VippsErrorException.php │ ├── VippsException.php │ └── WrongAmountException.php ├── Http │ ├── Client │ │ ├── ClientInterface.php │ │ └── Curl.php │ └── TransferFactory.php ├── Request │ ├── BuilderComposite.php │ ├── GenericDataBuilder.php │ ├── Initiate │ │ ├── CustomerDataBuilder.php │ │ ├── InitPreprocessor.php │ │ ├── InitiateBuilderInterface.php │ │ ├── MerchantDataBuilder.php │ │ └── TransactionDataBuilder.php │ ├── MerchantDataBuilder.php │ ├── SendReceipt │ │ ├── BottomLineBuilder.php │ │ ├── GenericDataBuilder.php │ │ └── OrderLinesBuilder.php │ ├── ShouldReleaseRemainingFunds.php │ ├── SubjectReader.php │ ├── TransactionDataBuilder.php │ └── TransactionTextDataBuilder.php ├── Response │ ├── InitiateHandler.php │ └── TransactionHandler.php ├── Transaction │ ├── ShippingDetails.php │ ├── Transaction.php │ ├── TransactionBuilder.php │ ├── TransactionInfo.php │ ├── TransactionLogHistory.php │ ├── TransactionLogHistory │ │ └── Item.php │ ├── TransactionSummary.php │ └── UserDetails.php └── Validator │ ├── AvailabilityValidator.php │ ├── AvailabilityValidatorProxy.php │ ├── CancelTransactionValidator.php │ ├── CaptureTransactionValidator.php │ ├── InitiateValidator.php │ ├── OrderValidator.php │ └── RefundTransactionValidator.php ├── GatewayEpayment ├── Command │ ├── CancelCommand.php │ ├── CaptureCommand.php │ ├── CommandManager.php │ ├── GatewayCommand.php │ ├── PaymentCommandManager.php │ ├── PaymentDetailsProvider.php │ ├── PaymentsPostCommand.php │ └── RefundCommand.php ├── Data │ ├── Aggregate.php │ ├── AggregateFactory.php │ ├── Amount.php │ ├── BillingDetails.php │ ├── Customer.php │ ├── InitSession.php │ ├── InitSessionBuilder.php │ ├── Payment.php │ ├── PaymentBuilder.php │ ├── PaymentDetails.php │ ├── PaymentEventLog.php │ ├── PaymentEventLog │ │ └── Item.php │ ├── PaymentEventLogBuilder.php │ ├── PaymentMethod.php │ ├── Profile.php │ ├── Session.php │ ├── SessionBuilder.php │ └── ShippingDetails.php ├── Exception │ ├── AuthenticationException.php │ ├── VippsException.php │ └── WrongAmountException.php ├── Http │ ├── Client │ │ ├── CheckoutCurl.php │ │ ├── ClientInterface.php │ │ └── PaymentCurl.php │ ├── Transfer.php │ ├── TransferBuilder.php │ ├── TransferFactory.php │ ├── TransferFactoryInterface.php │ └── TransferInterface.php ├── Model │ ├── PaymentEventLogProvider.php │ ├── PaymentProvider.php │ └── TransactionProcessor.php ├── Request │ ├── AdjustAuthorization │ │ └── AuthorisationTypeBuilder.php │ ├── DefaultDataBuilder.php │ ├── GetSession │ │ ├── ReferenceDataBuilder.php │ │ └── SessionIdDataBuilder.php │ ├── InitSession │ │ ├── AddressFieldsDataBuilder.php │ │ ├── ConfigurationDataBuilder.php │ │ ├── ContactFieldsDataBuilder.php │ │ ├── CustomerDataBuilder.php │ │ ├── InitPreprocessor.php │ │ ├── MerchantDataBuilder.php │ │ └── TransactionDataBuilder.php │ ├── ModificationDataBuilder.php │ ├── Payment │ │ └── AmountBuilder.php │ ├── ReferenceDataBuilder.php │ ├── SendReceipt │ │ ├── BottomLineBuilder.php │ │ ├── GenericDataBuilder.php │ │ └── OrderLinesBuilder.php │ └── SubjectReader.php ├── Response │ ├── GetSessionHandler.php │ ├── InitSessionHandler.php │ └── Payment │ │ ├── PostHandler.php │ │ └── TransactionHandler.php └── Validator │ ├── AvailabilityValidator.php │ ├── CancelTransactionValidator.php │ ├── CaptureTransactionValidator.php │ ├── InitiateValidator.php │ ├── OrderValidator.php │ ├── ReferenceValidator.php │ └── RefundTransactionValidator.php ├── GraphQl └── Resolver │ ├── ActivateCart.php │ ├── GetPaymentDetails.php │ ├── GetPaymentLabel.php │ └── InitPayment.php ├── Jenkinsfile ├── LICENSE ├── Model ├── Adminhtml │ └── Source │ │ ├── Cancellation │ │ └── Type.php │ │ ├── Environment.php │ │ ├── OrderStatus.php │ │ └── PaymentAction.php ├── Checkout │ └── ConfigProvider.php ├── CommandPoolProxy.php ├── Config │ ├── ConfigVersionPool.php │ └── Source │ │ ├── Email │ │ └── Template.php │ │ └── Version.php ├── CurrencyValidator.php ├── Exception │ └── AcquireLockException.php ├── Fallback │ ├── Authorise │ │ ├── Commerce.php │ │ └── Epayment.php │ └── AuthoriseProxy.php ├── Gdpr │ └── Compliance.php ├── Helper │ └── Utility.php ├── LockManager.php ├── LockManagerInterface.php ├── Logger │ └── Handler │ │ ├── Debug.php │ │ └── Error.php ├── Method │ └── Vipps.php ├── ModuleMetadata.php ├── ModuleMetadataInterface.php ├── Order │ ├── Cancellation │ │ └── Config.php │ └── PartialVoid │ │ ├── Config.php │ │ └── SendMail.php ├── OrderLocator.php ├── PaymentEventLogProvider.php ├── PaymentProvider.php ├── Profiling │ ├── Item.php │ ├── ItemRepository.php │ ├── Profiler.php │ ├── ProfilerInterface.php │ └── TypeInterface.php ├── Quote.php ├── Quote │ ├── AddressUpdater.php │ ├── Attempt.php │ ├── AttemptManagement.php │ ├── AttemptRepository.php │ ├── CancelFacade.php │ ├── Command │ │ ├── ManualCancel.php │ │ ├── ManualCancelFactory.php │ │ ├── Restart.php │ │ └── RestartFactory.php │ └── ShippingMethodValidator.php ├── QuoteLocator.php ├── QuoteManagement.php ├── QuoteRepository.php ├── QuoteUpdater.php ├── ResourceModel │ ├── Profiling │ │ ├── Item.php │ │ └── Item │ │ │ └── Collection.php │ ├── Quote.php │ └── Quote │ │ ├── Attempt.php │ │ ├── Attempt │ │ └── Collection.php │ │ ├── Collection.php │ │ └── GridCollection.php ├── Source │ ├── Position.php │ └── RequestTypes.php ├── System │ └── Message │ │ └── Notification │ │ └── ExpressCheckout │ │ └── TaxConfigurationError.php ├── TokenProvider.php ├── TokenProviderInterface.php ├── Transaction │ ├── PaymentDetailsProxy.php │ └── StatusVisitor.php ├── TransactionProcessor.php └── UrlResolver.php ├── Observer ├── AddVippsShortcutsObserver.php ├── AvailabilityByShippingMethod.php ├── CheckoutSubmitAllAfter.php ├── CheckoutSubmitBefore.php ├── OrderPaymentAfter.php └── SendOfflineVoidEmail.php ├── Plugin ├── Config │ └── Model │ │ └── Config.php └── Sales │ └── OrderManagement │ └── AfterPlaceOrder.php ├── README.md ├── Test ├── Integration │ └── Controller │ │ └── Payment │ │ ├── FallbackTest.php │ │ └── Klarna │ │ └── InitRegularTest.php └── Unit │ ├── Controller │ └── Payment │ │ ├── FallbackTest.php │ │ ├── ShippingDetailsTest.php │ │ └── _files │ │ ├── cancelled_transaction.php │ │ ├── could_not_acquire_lock.php │ │ └── reserved_transaction.php │ ├── Gateway │ ├── Command │ │ └── GatewayCommandTest.php │ ├── Http │ │ └── Client │ │ │ └── CurlTest.php │ ├── Response │ │ └── TransactionHandlerTest.php │ └── Transaction │ │ ├── TransactionTest.php │ │ └── _files │ │ ├── expired_transaction_case01.php │ │ ├── expired_transaction_case02.php │ │ ├── initiated_transaction_case01.php │ │ ├── initiated_transaction_case02.php │ │ ├── initiated_transaction_case03.php │ │ ├── initiated_transaction_case04.php │ │ ├── reserved_transaction_case01.php │ │ ├── reserved_transaction_case02.php │ │ └── reserved_transaction_case03.php │ ├── Model │ ├── ModuleMetadataTest.php │ └── TokenProviderTest.php │ └── bootstrap.php ├── Ui └── Component │ ├── Column │ ├── ShowAction.php │ └── Status.php │ └── Profiling │ └── Column │ └── FormattedValue.php ├── composer.json ├── docs ├── FAQ.md ├── documentation.md └── images │ ├── cancellation_settings.png │ ├── checkout_settings.png │ ├── express-checkout-notice.png │ ├── express_vipps_settings.png │ ├── klarna_checkout.png │ ├── mp.png │ ├── quote-monitoring-flow.png │ ├── request_profiling.png │ ├── tax-origin-settings.png │ ├── vaimo.svg │ ├── vaimo_dark.svg │ ├── vipps.png │ ├── vipps_additional_settings.png │ ├── vipps_basic.png │ ├── vipps_basic_v2.png │ └── vipps_method.png ├── etc ├── acl.xml ├── adminhtml │ ├── di.xml │ ├── menu.xml │ ├── routes.xml │ ├── system.xml │ └── system │ │ ├── cancellation.xml │ │ ├── checkout.xml │ │ ├── express_checkout.xml │ │ └── partial_void.xml ├── config.xml ├── crontab.xml ├── db_schema.xml ├── db_schema_whitelist.json ├── di.xml ├── email_templates.xml ├── events.xml ├── extension_attributes.xml ├── frontend │ ├── di.xml │ ├── events.xml │ └── routes.xml ├── graphql │ └── di.xml ├── klarna.xml ├── module.xml ├── schema.graphqls └── webapi_rest │ └── di.xml ├── i18n ├── da_DK.csv ├── fi_FI.csv └── nb_NO.csv ├── phpcs.xml ├── phpmd.xml ├── phpunit.xml ├── registration.php └── view ├── adminhtml ├── layout │ ├── adminhtml_system_config_edit.xml │ ├── sales_order_create_index.xml │ ├── sales_order_create_load_block_billing_method.xml │ ├── sales_order_view.xml │ ├── vipps_monitoring_index.xml │ ├── vipps_monitoring_view.xml │ ├── vipps_profiling_index.xml │ └── vipps_profiling_view.xml ├── requirejs-config.js ├── templates │ ├── monitoring │ │ ├── buttons.phtml │ │ └── view.phtml │ ├── order │ │ └── view │ │ │ └── info │ │ │ └── payment_info.phtml │ ├── profiling │ │ ├── back_button.phtml │ │ └── view.phtml │ └── system │ │ └── config │ │ └── testcredentials.phtml ├── ui_component │ ├── vipps_monitoring.xml │ └── vipps_profiling.xml └── web │ ├── js │ └── testcredentials.js │ └── styles.css ├── base └── web │ └── images │ ├── Vipps_MobilePay_Logo_Primary_RGB_Black.png │ ├── Vipps_MobilePay_Logo_Primary_RGB_White.png │ ├── mobilepay_logo.png │ ├── vipps_logo_69x24.png │ ├── vipps_logo_negativ_rgb.png │ └── vipps_logo_rgb.png └── frontend ├── email └── partial_void.html ├── layout ├── checkout_index_index.xml ├── default.xml └── vipps_email_partial_order.xml ├── templates ├── button.phtml └── email │ └── items │ └── order │ └── default.phtml └── web ├── css └── vipps_styles.css ├── images ├── vipps-hurtigkasse.svg ├── vipps_express.svg ├── vipps_knapp_fortsett.png ├── vipps_knapp_hurtigkasse.png ├── vipps_knapp_logginn.png ├── vipps_knapp_logginn_01.png └── vipps_logo_100x26.png ├── js └── view │ ├── payment │ ├── method-renderer │ │ └── vipps.js │ └── vipps.js │ └── vipps-express-checkout.js └── template └── payment └── vipps.html /.gitignore: -------------------------------------------------------------------------------- 1 | .hgignore 2 | vendor/ 3 | .idea/ 4 | .hg/ 5 | composer.lock 6 | Jenkinsfile 7 | -------------------------------------------------------------------------------- /Api/Fallback/AuthoriseInterface.php: -------------------------------------------------------------------------------- 1 | order) { 42 | $this->order = clone $this->getData('order'); 43 | $items = $this->order->getItems(); 44 | foreach ($items as $key => $item) { 45 | if (!$item->getQtyCanceled()) { 46 | unset($items[$key]); 47 | } 48 | } 49 | $this->order->setItems($items); 50 | } 51 | 52 | return $this->order; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Block/Profiling/View.php: -------------------------------------------------------------------------------- 1 | item = $item; 47 | } 48 | 49 | /** 50 | * Retrieve profiling item 51 | * 52 | * @return Item 53 | */ 54 | public function getItem() 55 | { 56 | if (!$this->item->getId()) { 57 | $entityId = $this->getRequest()->getParam('entity_id', null); 58 | if ($entityId) { 59 | $this->item->load($entityId); 60 | } 61 | } 62 | return $this->item; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Gateway/Exception/AuthenticationException.php: -------------------------------------------------------------------------------- 1 | [ 44 | 'currency' => $order->getStoreCurrencyCode(), 45 | 'tipAmount' => 0, 46 | 'giftCardAmount' => 0, 47 | 'terminalId' => null 48 | ] 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Gateway/Request/SendReceipt/GenericDataBuilder.php: -------------------------------------------------------------------------------- 1 | $order->getIncrementId()]; 40 | } 41 | 42 | return []; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Gateway/Validator/AvailabilityValidatorProxy.php: -------------------------------------------------------------------------------- 1 | configVersionPool = $configVersionPool; 28 | } 29 | 30 | private function get(): ValidatorInterface 31 | { 32 | return $this->configVersionPool->get(); 33 | } 34 | 35 | public function validate(array $validationSubject) 36 | { 37 | return $this->get()->validate($validationSubject); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Gateway/Validator/InitiateValidator.php: -------------------------------------------------------------------------------- 1 | createResult($isValid, $errorMessages); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /GatewayEpayment/Data/Amount.php: -------------------------------------------------------------------------------- 1 | getData(self::CURRENCY); 43 | } 44 | 45 | /** 46 | * @return int|null 47 | */ 48 | public function getValue() 49 | { 50 | return $this->getData(self::VALUE); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /GatewayEpayment/Data/Customer.php: -------------------------------------------------------------------------------- 1 | getData(self::PHONE_NUMBER); 43 | } 44 | 45 | /** 46 | * @return string 47 | */ 48 | public function getSub(): string 49 | { 50 | return (string)$this->getData(self::SUB); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /GatewayEpayment/Data/InitSession.php: -------------------------------------------------------------------------------- 1 | getData(self::TOKEN); 46 | } 47 | 48 | /** 49 | * @return string 50 | */ 51 | public function getCheckoutFrontendUrl() 52 | { 53 | return $this->getData(self::CHECKOUT_FRONTEND_URL); 54 | } 55 | 56 | /** 57 | * @return string 58 | */ 59 | public function getPollingUrl() 60 | { 61 | return $this->getData(self::POLLING_URL); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /GatewayEpayment/Data/PaymentEventLog.php: -------------------------------------------------------------------------------- 1 | getData(self::ITEMS); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /GatewayEpayment/Data/PaymentMethod.php: -------------------------------------------------------------------------------- 1 | getData(self::TYPE); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /GatewayEpayment/Data/Profile.php: -------------------------------------------------------------------------------- 1 | getData(self::SCOPE); 43 | } 44 | 45 | /** 46 | * @return string 47 | */ 48 | public function getSub() 49 | { 50 | return $this->getData(self::SUB); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /GatewayEpayment/Exception/AuthenticationException.php: -------------------------------------------------------------------------------- 1 | 'FINAL_AUTH']; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /GatewayEpayment/Request/DefaultDataBuilder.php: -------------------------------------------------------------------------------- 1 | $buildSubject['reference'] 38 | ]; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /GatewayEpayment/Request/GetSession/SessionIdDataBuilder.php: -------------------------------------------------------------------------------- 1 | $buildSubject['session_id'] 38 | ]; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /GatewayEpayment/Request/InitSession/AddressFieldsDataBuilder.php: -------------------------------------------------------------------------------- 1 | true 38 | ]; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /GatewayEpayment/Request/InitSession/ContactFieldsDataBuilder.php: -------------------------------------------------------------------------------- 1 | true 38 | ]; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /GatewayEpayment/Request/ReferenceDataBuilder.php: -------------------------------------------------------------------------------- 1 | subjectReader = $subjectReader; 28 | } 29 | 30 | /** 31 | * This builders for passing parameters into TransferFactory object. 32 | */ 33 | public function build(array $buildSubject): array 34 | { 35 | $paymentDO = $this->subjectReader->readPayment($buildSubject); 36 | if ($paymentDO) { 37 | $orderAdapter = $paymentDO->getOrder(); 38 | if ($orderAdapter) { 39 | $buildSubject = array_merge( 40 | $buildSubject, 41 | ['reference' => $orderAdapter->getOrderIncrementId()] 42 | ); 43 | } 44 | } 45 | 46 | return $buildSubject; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /GatewayEpayment/Request/SendReceipt/BottomLineBuilder.php: -------------------------------------------------------------------------------- 1 | [ 37 | 'currency' => $order->getStoreCurrencyCode(), 38 | 'tipAmount' => 0, 39 | 'giftCardAmount' => 0, 40 | 'terminalId' => null 41 | ] 42 | ]; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /GatewayEpayment/Request/SendReceipt/GenericDataBuilder.php: -------------------------------------------------------------------------------- 1 | $order->getIncrementId()]; 33 | } 34 | 35 | return []; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /GatewayEpayment/Request/SubjectReader.php: -------------------------------------------------------------------------------- 1 | createResult($isValid, $errorMessages); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /GraphQl/Resolver/GetPaymentLabel.php: -------------------------------------------------------------------------------- 1 | vipps = $vipps; 40 | } 41 | 42 | public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null): string 43 | { 44 | return (string)$this->vipps->getTitle(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!groovy 2 | 3 | @Library('platform-jenkins-pipeline') _ 4 | 5 | pipeline { 6 | agent { label 'magento24' } 7 | options { 8 | ansiColor('xterm') 9 | } 10 | stages { 11 | stage('Checkout Module') { 12 | steps { 13 | git branch: '$BRANCH_NAME', url: 'git@bitbucket.org:vaimo/module-vipps-payment.git' 14 | sh 'composer install --no-ansi' 15 | } 16 | } 17 | stage('PHP Unit') { 18 | steps { 19 | sh './vendor/bin/phpunit -c phpunit.xml' 20 | } 21 | } 22 | } 23 | 24 | post { 25 | always { 26 | sendNotifications() 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Vipps AS 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Model/Adminhtml/Source/Cancellation/Type.php: -------------------------------------------------------------------------------- 1 | self::AUTOMATIC, 46 | 'label' => __('Automatic'), 47 | ], 48 | [ 49 | 'value' => self::MANUAL, 50 | 'label' => __('Manual'), 51 | ] 52 | ]; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Model/Adminhtml/Source/Environment.php: -------------------------------------------------------------------------------- 1 | self::ENVIRONMENT_DEVELOP, 45 | 'label' => 'Develop', 46 | ], 47 | [ 48 | 'value' => self::ENVIRONMENT_PRODUCTION, 49 | 'label' => 'Production' 50 | ] 51 | ]; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Model/Adminhtml/Source/OrderStatus.php: -------------------------------------------------------------------------------- 1 | self::STATUS_PAYMENT_REVIEW, 45 | 'label' => __('Payment Review'), 46 | ], 47 | [ 48 | 'value' => self::STATUS_PENDING, 49 | 'label' => __('Pending'), 50 | ] 51 | ]; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Model/Adminhtml/Source/PaymentAction.php: -------------------------------------------------------------------------------- 1 | self::ACTION_AUTHORIZE, 45 | 'label' => __('Authorize'), 46 | ], 47 | [ 48 | 'value' => self::ACTION_AUTHORIZE_CAPTURE, 49 | 'label' => __('Authorize and Capture'), 50 | ] 51 | ]; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Model/CommandPoolProxy.php: -------------------------------------------------------------------------------- 1 | configVersionPool = $configVersionPool; 17 | } 18 | 19 | private function getPool(): CommandPoolInterface 20 | { 21 | return $this->configVersionPool->get(); 22 | } 23 | 24 | public function get($commandCode): CommandInterface 25 | { 26 | return $this->getPool()->get($commandCode); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Model/Config/ConfigVersionPool.php: -------------------------------------------------------------------------------- 1 | pool = $pool; 20 | $this->config = $config; 21 | } 22 | 23 | public function get() 24 | { 25 | $versionCode = $this->config->getVersion(); 26 | 27 | return $this->pool[$versionCode] ?? $this->pool[Version::CONFIG_VIPPS]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Model/Config/Source/Version.php: -------------------------------------------------------------------------------- 1 | self::CONFIG_VIPPS, 'label' => __(self::LABEL_VIPPS)], 26 | ['value' => self::CONFIG_MOBILE_EPAYMENT, 'label' => __(self::LABEL_MOBILE_PAY)] 27 | ]; 28 | } 29 | 30 | /** 31 | * Get options in "key-value" format 32 | * 33 | * @return array 34 | */ 35 | public function toArray() 36 | { 37 | return [self::CONFIG_VIPPS => __(self::LABEL_VIPPS), self::CONFIG_MOBILE_EPAYMENT => __(self::LABEL_MOBILE_PAY)]; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Model/CurrencyValidator.php: -------------------------------------------------------------------------------- 1 | storeManager = $storeManager; 46 | } 47 | 48 | /** 49 | * Validate if Norwegian currency is selected in store configuration. 50 | * 51 | * @return bool 52 | * @throws NoSuchEntityException 53 | */ 54 | public function isValid(): bool 55 | { 56 | /** @var Store $store */ 57 | $store = $this->storeManager->getStore(); 58 | 59 | return self::NORWEGIAN_CURRENCY == $store->getBaseCurrencyCode(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Model/Exception/AcquireLockException.php: -------------------------------------------------------------------------------- 1 | getParam('order_id') || 17 | !$request->getParam('auth_token') 18 | ) { 19 | throw new LocalizedException(__('Invalid request parameters')); 20 | } 21 | 22 | if ($vippsQuote->getAuthToken() !== $request->getParam('auth_token', '')) { 23 | throw new LocalizedException(__('Invalid request')); 24 | } 25 | } 26 | 27 | public function getOrderId(RequestInterface $request): string 28 | { 29 | return $request->getParam('order_id'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Model/Fallback/Authorise/Epayment.php: -------------------------------------------------------------------------------- 1 | getParam('reference')) { 17 | throw new LocalizedException(__('Invalid request parameters')); 18 | } 19 | 20 | if ($vippsQuote->getReservedOrderId() !== $request->getParam('reference', '')) { 21 | throw new LocalizedException(__('Invalid request')); 22 | } 23 | } 24 | 25 | public function getOrderId(RequestInterface $request): string 26 | { 27 | return $request->getParam('reference'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Model/Fallback/AuthoriseProxy.php: -------------------------------------------------------------------------------- 1 | configVersionPool = $configVersionPool; 19 | } 20 | 21 | private function get(): AuthoriseInterface 22 | { 23 | return $this->configVersionPool->get(); 24 | } 25 | 26 | public function do(RequestInterface $request, QuoteInterface $vippsQuote): void 27 | { 28 | $this->get()->do($request, $vippsQuote); 29 | } 30 | 31 | public function getOrderId(RequestInterface $request): string 32 | { 33 | return $this->get()->getOrderId($request); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Model/Helper/Utility.php: -------------------------------------------------------------------------------- 1 | getBillingAddress(); 32 | $billingAddress->setShouldIgnoreValidation(true); 33 | 34 | if (!$quote->getIsVirtual()) { 35 | $shippingAddress = $quote->getShippingAddress(); 36 | $shippingAddress->setShouldIgnoreValidation(true); 37 | if (!$billingAddress->getEmail()) { 38 | $billingAddress->setSameAsBilling(1); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Model/LockManagerInterface.php: -------------------------------------------------------------------------------- 1 | getConfigData('version'); 36 | 37 | return $this->getConfigData('title_' . $version); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Model/ModuleMetadataInterface.php: -------------------------------------------------------------------------------- 1 | objectManager = $objectManager; 39 | } 40 | 41 | /** 42 | * @param QuoteInterface $vippsQuote 43 | * @return ManualCancel 44 | */ 45 | public function create(QuoteInterface $vippsQuote) 46 | { 47 | return $this->objectManager->create(ManualCancel::class, ['vippsQuote' => $vippsQuote]); //@codingStandardsIgnoreLine 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Model/Quote/Command/RestartFactory.php: -------------------------------------------------------------------------------- 1 | objectManager = $objectManager; 39 | } 40 | 41 | /** 42 | * @param QuoteInterface $vippsQuote 43 | * @return Restart 44 | */ 45 | public function create(QuoteInterface $vippsQuote) 46 | { 47 | return $this->objectManager->create(Restart::class, ['vippsQuote' => $vippsQuote]); //@codingStandardsIgnoreLine 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Model/ResourceModel/Profiling/Item.php: -------------------------------------------------------------------------------- 1 | _init(self::TABLE_NAME, self::INDEX_FIELD); 42 | } 43 | 44 | /** 45 | * Delete entity by id 46 | * 47 | * @param $id 48 | */ 49 | public function deleteById($id) 50 | { 51 | $connection = $this->getConnection(); 52 | $connection->delete(self::TABLE_NAME, [self::INDEX_FIELD . ' = ?' => $id]); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Model/ResourceModel/Quote/Attempt.php: -------------------------------------------------------------------------------- 1 | _init(self::TABLE_NAME, self::INDEX_FIELD); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Model/ResourceModel/Quote/Attempt/Collection.php: -------------------------------------------------------------------------------- 1 | _init(AttemptModel::class, AttemptResource::class); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Model/ResourceModel/Quote/Collection.php: -------------------------------------------------------------------------------- 1 | _init(QuoteModel::class, QuoteResource::class); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Model/TokenProviderInterface.php: -------------------------------------------------------------------------------- 1 | configVersionPool = $configVersionPool; 17 | } 18 | 19 | private function getPaymentDetailsCommand(): \Vipps\Payment\Api\Transaction\PaymentDetailsInterface 20 | { 21 | return $this->configVersionPool->get(); 22 | } 23 | 24 | public function get($incrementId) 25 | { 26 | return $this->getPaymentDetailsCommand()->get($incrementId); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Model/Transaction/StatusVisitor.php: -------------------------------------------------------------------------------- 1 | isTransactionExpired(); 16 | } 17 | 18 | if ($transaction instanceof Payment) { 19 | return $transaction->isExpired(); 20 | } 21 | 22 | return false; 23 | } 24 | 25 | public function isCanceled($transaction): bool 26 | { 27 | if ($transaction instanceof Transaction) { 28 | return $transaction->transactionWasCancelled(); 29 | } 30 | 31 | if ($transaction instanceof Payment) { 32 | return $transaction->isTerminated(); 33 | } 34 | 35 | return false; 36 | } 37 | 38 | public function isVoided($transaction): bool 39 | { 40 | if ($transaction instanceof Transaction) { 41 | return $transaction->transactionWasVoided(); 42 | } 43 | 44 | if ($transaction instanceof Payment) { 45 | return $transaction->isAborter(); 46 | } 47 | 48 | return false; 49 | } 50 | 51 | public function isAuthorised($transaction): bool 52 | { 53 | if ($transaction instanceof Payment) { 54 | return $transaction->isAuthorised(); 55 | } 56 | 57 | return false; 58 | } 59 | 60 | public function isReserved($transaction): bool 61 | { 62 | if ($transaction instanceof Transaction) { 63 | return $transaction->isTransactionReserved(); 64 | } 65 | 66 | if ($transaction instanceof Payment) { 67 | return $transaction->isAuthorised(); 68 | } 69 | 70 | return false; 71 | } 72 | 73 | public function isCaptured($transaction): bool 74 | { 75 | if ($transaction instanceof Transaction) { 76 | return $transaction->isTransactionCaptured(); 77 | } 78 | 79 | return false; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Plugin/Sales/OrderManagement/AfterPlaceOrder.php: -------------------------------------------------------------------------------- 1 | getPayment()->getMethod()) { 38 | $order->setCanSendNewEmailFlag(false); 39 | } 40 | 41 | return $order; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Test/Unit/Controller/Payment/_files/cancelled_transaction.php: -------------------------------------------------------------------------------- 1 | getData('name')]) > static::$charactersLimitToShow) { 44 | $item[$this->getData('name')] = 45 | substr($item[$this->getData('name')], 0, static::$charactersLimitToShow) . ' ...'; 46 | } 47 | } 48 | } 49 | 50 | return $dataSource; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vipps/module-payment", 3 | "type": "magento2-module", 4 | "description": "Vipps MobilePay Payment Module for Magento 2", 5 | "license": "proprietary", 6 | "require": { 7 | "magento/framework": "101.0.*|103.0.*", 8 | "magento/module-sales": "101.0.*|103.0.*", 9 | "magento/module-payment": "100.2.*|100.4.*", 10 | "magento/module-checkout": "100.2.*|100.4.*", 11 | "psr/log": "^1.0||^2.0||^3.0" 12 | }, 13 | "require-dev": { 14 | "phpmd/phpmd": "@stable", 15 | "phpunit/phpunit": "^9.0", 16 | "squizlabs/php_codesniffer": "@stable" 17 | }, 18 | "autoload": { 19 | "files": [ 20 | "registration.php" 21 | ], 22 | "psr-4": { 23 | "Vipps\\Payment\\": "" 24 | } 25 | }, 26 | "extra": { 27 | "vaimo-module-category": "Integration" 28 | }, 29 | "repositories": { 30 | "magento": { 31 | "type": "composer", 32 | "url": "https://repo.magento.com/" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /docs/images/cancellation_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/cancellation_settings.png -------------------------------------------------------------------------------- /docs/images/checkout_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/checkout_settings.png -------------------------------------------------------------------------------- /docs/images/express-checkout-notice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/express-checkout-notice.png -------------------------------------------------------------------------------- /docs/images/express_vipps_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/express_vipps_settings.png -------------------------------------------------------------------------------- /docs/images/klarna_checkout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/klarna_checkout.png -------------------------------------------------------------------------------- /docs/images/mp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/mp.png -------------------------------------------------------------------------------- /docs/images/quote-monitoring-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/quote-monitoring-flow.png -------------------------------------------------------------------------------- /docs/images/request_profiling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/request_profiling.png -------------------------------------------------------------------------------- /docs/images/tax-origin-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/tax-origin-settings.png -------------------------------------------------------------------------------- /docs/images/vipps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/vipps.png -------------------------------------------------------------------------------- /docs/images/vipps_additional_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/vipps_additional_settings.png -------------------------------------------------------------------------------- /docs/images/vipps_basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/vipps_basic.png -------------------------------------------------------------------------------- /docs/images/vipps_basic_v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/vipps_basic_v2.png -------------------------------------------------------------------------------- /docs/images/vipps_method.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vippsas/vipps-magento/89f9a112b04efe1e5085ea2cacb0d8e86fc0ba2c/docs/images/vipps_method.png -------------------------------------------------------------------------------- /etc/acl.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /etc/adminhtml/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | Vipps\Payment\Model\System\Message\Notification\ExpressCheckout\TaxConfigurationError 21 | 22 | 23 | 24 | 25 | 26 | 27 | Vipps\Payment\Gateway\Config\Config 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /etc/adminhtml/routes.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /etc/adminhtml/system/checkout.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | 1 22 | Magento\Shipping\Model\Config\Source\Allmethods 23 | payment/vipps/disallowed_shipping_methods 24 | 25 | 26 | 27 | 28 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /etc/crontab.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | */10 * * * * 20 | 21 | 22 | 0 * * * * 23 | 24 | 25 | 0 0 * * * 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /etc/db_schema_whitelist.json: -------------------------------------------------------------------------------- 1 | { 2 | "vipps_payment_jwt": { 3 | "column": { 4 | "token_id": true, 5 | "scope_id": true, 6 | "token_type": true, 7 | "expires_in": true, 8 | "ext_expires_in": true, 9 | "expires_on": true, 10 | "not_before": true, 11 | "resource": true, 12 | "access_token": true, 13 | "scope": true 14 | }, 15 | "constraint": { 16 | "PRIMARY": true 17 | } 18 | }, 19 | "vipps_profiling": { 20 | "column": { 21 | "entity_id": true, 22 | "increment_id": true, 23 | "status_code": true, 24 | "request_type": true, 25 | "request": true, 26 | "response": true, 27 | "created_at": true 28 | }, 29 | "constraint": { 30 | "PRIMARY": true 31 | } 32 | }, 33 | "vipps_quote": { 34 | "column": { 35 | "entity_id": true, 36 | "quote_id": true, 37 | "reserved_order_id": true, 38 | "attempts": true, 39 | "created_at": true, 40 | "updated_at": true, 41 | "status": true, 42 | "store_id": true, 43 | "order_id": true, 44 | "auth_token": true 45 | }, 46 | "index": { 47 | "VIPPS_QUOTE_QUOTE_ID": true 48 | }, 49 | "constraint": { 50 | "PRIMARY": true, 51 | "VIPPS_QUOTE_QUOTE_ID_QUOTE_ENTITY_ID": true, 52 | "VIPPS_QUOTE_RESERVED_ORDER_ID": true, 53 | "VIPPS_QUOTE_ORDER_ID": true 54 | } 55 | }, 56 | "vipps_quote_attempt": { 57 | "column": { 58 | "entity_id": true, 59 | "parent_id": true, 60 | "message": true, 61 | "created_at": true 62 | }, 63 | "constraint": { 64 | "PRIMARY": true, 65 | "VIPPS_QUOTE_ATTEMPT_PARENT_ID_VIPPS_QUOTE_ENTITY_ID": true 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /etc/email_templates.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 |