Code Monkey home page Code Monkey logo

hybris's Introduction

Worldpay Connector for the SAP Commerce Cloud

The Worldpay Connector for SAP Commerce Cloud is a seamless extension to the Commerce storefront, enabling retailers to implement their global payment strategy through a single integration in a secure, compliant and unified approach. The extensive WorldPay extension enables retailers to gain access to: Global and regional payment methods, a variety of integration options, customisable hosted payment pages, 3D Secure and market leading fraud screening (RiskGuardian™). The Connector is SAP Premium Certified. About Worldpay: Worldpay (formerly RBS WorldPay) is a payment processing company. The company provides payment services for mail order and Internet retailers, as well as point of sale transactions. Customers are a mix of multinational, multichannel retailers, with the majority being small business merchants. It also provides loans to small businesses.

Introduction

SAP Commerce Cloud

The extension is crafted for SAP Commerce Cloud as well previous versions of what was formerly called Hybris.

Release Information

This release is tailored for SAP Commerce Cloud 2211. It is advised to use the latest release available in Github to get the benefits of newest development made to this extension.

Installation and Usage

Installing the Plugin using the provided recipes

The AddOn provides three gradle recipes to be used with the hybris installer.

  1. wp_b2c_acc with fulfilment functionality for both accelerator storefront and OCC.

  2. wp_b2c_acc_oms with OMS functionality for both accelerator storefront and OCC.

  3. wp_b2b_acc with fulfilment functionality for b2b accelerator storefront.

  4. wp_b2c_acc_occ with fulfilment functionality for b2c accelerator storefront and extra porperties for Spartacus.

The recipes are based on the b2c_acc, b2c_acc_oms and b2b_acc recipes provided by hybris.

The recipes can be found under the installer folder.

To use the recipes on a clean hybris installation, copy the folder hybris to your ${HYBRIS_BIN_DIR}

Since the recipe generates the local.properties file with the properties defined in the recipe, optionally you can add your local.properties to the customconfig folder.

In order to install the AddOn using one of the recipes, run the following commands:

  • This will run setup, build, initialize and start HYBRIS_HOME/installer$ ./install.sh -r [RECIPE_NAME] perform

RELEASE NOTES

Features:

  • Added PayPal-SSL

Breaking changes:

  • iDeal 2.0 implemented

hybris's People

Contributors

adbame avatar alejandropiqueres avatar damian229 avatar danisanga avatar eusebiotrigo avatar lochansim avatar martincrowell avatar quim3ra avatar racuevji avatar slleshi12 avatar thomasryegaardchristensen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hybris's Issues

Incorrect spring wiring in worldpaynotifications

orderModificationProcessorJobPerformable is using worldpayOrderModificationProcessService for the constructor-arg but it should use it's alias to allow for custom extensions, based on worldpaynotifications to override the logic without the need of changing any of the worldpaynotifications code.

    <bean id="orderModificationProcessorJobPerformable" class="com.worldpay.cronjob.OrderModificationProcessorJobPerformable" parent="abstractJobPerformable">
        <constructor-arg name="worldpayOrderModificationProcessService" ref="worldpayOrderModificationProcessService"/>
    </bean>

should be changed to:

    <bean id="orderModificationProcessorJobPerformable" class="com.worldpay.cronjob.OrderModificationProcessorJobPerformable" parent="abstractJobPerformable">
        <constructor-arg name="worldpayOrderModificationProcessService" ref="orderModificationProcessStrategy"/>
    </bean>

This plugin's implementation of CardPaymentService is incomplete

This plugin's implementation of CardPaymentService is incomplete, given that 8 out of 12 logically possible commands are absent from worldpayapi. See https://github.com/Worldpay/hybris/tree/master/hybris/bin/y-ext/ext-worldpay/worldpayapi/src/com/worldpay/commands/impl

The commands whose implementation appear to be absent are:

  • SubscriptionAuthorizationCommand
  • PartialCaptureCommand
  • EnrollmentCheckCommand
  • StandaloneRefundCommand
  • CreateSubscriptionCommand
  • UpdateSubscriptionCommand
  • GetSubscriptionDataCommand
  • DeleteSubscriptionCommand

The business impact as far as I can tell are:

  • If a merchant wants to have split payment captures for a single authorization, then their implementation partner will have to implement PartialCaptureCommand
  • If a merchant wants to have saved cards via a subscription, then their implementation partner will have to implement SubscriptionAuthorizationCommand, CreateSubscriptionCommand, UpdateSubscriptionCommand, GetSubscriptionDataCommand, DeleteSubscriptionCommand
  • If a merchant wants to have good will refunds, then their implementation partner will have to implement StandaloneRefundCommand

`java.lang.ClassCastException` when a worldpay order code relates to a cart that has the transaction type set to `AUTHORIZATION`

Hello again, worldpay team, we've encountered another issue with the latest 1905_7.0 release:

When the new DefaultWorldpayOrderModificationProcessService has been introduced, a class cast has creeped out of the if branch on this line. This causes an unhandled ClassCastException which crashes the OrderModificationProcessorJobPerformable completely and orders are stuck in Pending Payment Notification status.

Here is a unit test which you can add to DefaultWorldpayOrderModificationProcessServiceTest to reproduce the issue:

@Test
public void processOrderModificationMessages_WhenWorldpayOrderCodeRelatesToCartWithAuthorizationTransactionType_ShouldDoNothing() throws WorldpayConfigurationException {
    when(paymentTransactionModelMock.getOrder()).thenReturn(cartModelMock);

    final boolean result = testObj.processOrderModificationMessages(AUTHORIZATION);

    assertTrue(result);
    verify(worldpayOrderNotificationHandlerMock, never()).handleNotificationBusinessProcess(AUTHORIZATION, worldpayOrderModificationMock, orderModelMock, orderNotificationMessageMock);
    verify(worldpayOrderModificationMock, never()).setProcessed(Boolean.TRUE);
    verify(worldpayOrderModificationMock, never()).setDefective(any(Boolean.class));
}

Thank you for your support.

Regards.

Update documentation to explain licensing of these extensions

There is no license attached to this extension. Which license applies? MIT? Apache Software Foundation? Or maybe it's not even open source, and there's a cost for using these extensions?

At minimum I would assume that any retailer using these extensions has to have a contract to use WorldPay and Hybris, but that doesn't speak to the licensing or commercials of these extensions? Are these extensions an add-on product that WorldPay charges to its Hybris customers?

Change PAYPAL-EXPRESS to PAYPAL-SSL

Hi, as Worldpay notified they are going to change the type PAYPAL-EXPRESS to PAYPAL-SSL. I just want to ask do you have any plans to fix it in this project?
Kind regards,
Mohsen

Add release notes per merge to 'master'

@rselimi ,
Would you mind adding release notes for the last release to "master"? We'd like to upgrade to the latest and greatest version of your plugin. We'd like to understand what goes in the plugin.

NPE when the response from Worldpay is delayed by retry attempts

Hello Worldpay team, I am a backend engineer representing the Wilko project.

We've recently (Nov 16th) updated the worldpay plugin to 1905_7.0 version, and since then, we've been getting the following error:

Cannot invoke "org.springframework.http.ResponseEntity.getHeaders()" because "responseXML" is null, java.lang.NullPointerException in com.worldpay.service.http.impl.DefaultWorldpayConnector.processResponseXML(final ResponseEntity responseXML):111

It seems that, in some cases, the response from Worldpay request was getting passed as null into the processResponseXML() method. After some investigation, the root cause proved to be the use of the reactive API of RxJava on the following line

final Single<ResponseEntity<String>> response = sendOutboundXML(outboundPaymentService, merchantInfo, cookie);
response.subscribe(responseXML::set);
return processResponseXML(responseXML.get());

— the Single.subscribe() method is not blocking, and if the request takes a little bit longer than usual to return the response (for example it goes into the retry loop defined here), the responseXML.get() bit ends up being null, because the subscribe callback doesn't have a chance to set the response.

The logical question would be, why is this issue manifesting now more aggressively than before, since the above code hasn't been touched in the latest release? — the answer is the newly added delay. Adding a delay between the retry attempts, increased the odds of this issue manifesting itself more often than usual.

Here is a unit test, which you can add to DefaultWorldpayConnectorTest, to help reproduce this issue:

@Test
public void send_WhenTheResponseIsDelayedByRetries_ShouldSendThePaymentServiceTransformedInXML() throws Exception
{
    final var body = "body";
    final var cookie = "cookie";
    final var someXML = "someXML";
    final var inputStreamArgumentCaptor = ArgumentCaptor.forClass(InputStream.class);

    when(responseEntityMock.getHeaders()).thenReturn(httpHeadersMock);
    when(httpHeadersMock.get(HttpHeaders.SET_COOKIE)).thenReturn(List.of(cookie));
    when(responseEntityMock.getBody()).thenReturn(body);
    when(paymentServiceMarshallerMock.unmarshal(inputStreamArgumentCaptor.capture())).thenReturn(paymentServiceReplyMock);
    when(paymentServiceMarshallerMock.marshalAsFragment(paymentServiceRequestMock)).thenReturn(someXML);
    when(restTemplateMock.postForEntity(uriArgumentCaptor.capture(), httpEntityArgumentCaptor.capture(), eq(String.class)))
            .thenThrow(new ResourceAccessException(""))
            .thenThrow(new ResourceAccessException(""))
            .thenReturn(responseEntityMock);

    assertThat(testObj.send(paymentServiceRequestMock, merchantInfoMock, cookie))
            .extracting(ServiceReply::getPaymentService, ServiceReply::getCookie)
            .containsExactly(paymentServiceReplyMock, cookie);

    final var uri = uriArgumentCaptor.getValue();
    assertThat(uri.toString()).isEqualTo(ENDPOINT);

    final byte[] plainCreds = ("merchantCode" + ":" + "merchantPassword").getBytes(StandardCharsets.UTF_8);
    final var request = httpEntityArgumentCaptor.getValue();
    assertThat(request.getHeaders()).containsAllEntriesOf(Map.of(
            HttpHeaders.AUTHORIZATION, List.of("Basic " + new String(Base64.getEncoder().encode(plainCreds))),
            HttpHeaders.HOST, List.of(uri.getHost()),
            HttpHeaders.COOKIE, List.of(cookie)));
    assertThat(request.getBody()).startsWith(XML_HEADER).contains(someXML);
    assertThat(inputStreamArgumentCaptor.getValue()).hasSameContentAs(IOUtils.toInputStream(body, StandardCharsets.UTF_8));

    verify(restTemplateMock, times(3)).postForEntity(eq(URI.create(ENDPOINT)), anyObject(), eq(String.class));
}

Our current hotfix for this is to do

responseXML.set(response.toBlocking().value());

instead of

response.subscribe(responseXML::set);

however it would be nice to have this fixed upstream.

Hope this feedback was helpful to you.

P.S. something like RetryTemplate might be more fitting here instead of RxJava for the retry mechanism.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.