如何在单页应用程序中使用MPGS session.js。

huangapple go评论71阅读模式
英文:

How to work with MPGS session.js in an SPA

问题

根据您提供的信息,问题似乎是关于使用"session.js" SDK在单页面应用程序(SPA)中的配置和元素链接问题。问题似乎是在第一次调用PaymentSession.configure后,SDK与HTML元素建立链接,并且当页面导航后,SDK无法正确更新这些元素。MPGS支持建议不要删除和重新创建字段,而是隐藏/显示它们。

如果您需要进一步的帮助或有其他问题,请随时提出。

英文:

Following the docs from MPGS session we implemented the "session.js" SKD in a Single Page Application (SPA).

Some unexpected behaviour takes place... and the SDK malfuncitons as describbed below.

As we know modern SPA's add/remove html elements as the user navigates its pages. Keep this in the back of you mind while reading the issue description and MPGS's support answer below.

The first time (let us call it FIRST_CALL) the user arrives at the payment page we issue the PaymentSession.configure command as follows (the details object contains the correct ids of existing readonly input fields as required by the SDK):

PaymentSession.configure(
    {
        session: details.sessionId,
        fields: {
            card: {
                number: `#${details.htmlElementIdCardNumber}`,
                securityCode: `#${details.htmlElementIdCardCCV}`,
                expiryMonth: `#${details.htmlElementIdCardExpiryMonth}`,
                expiryYear: `#${details.htmlElementIdCardExpiryYear}`,
                nameOnCard: `#${details.htmlElementIdCardNameOnCard}`,
            },
        },
        frameEmbeddingMitigation: ['javascript'],
        callbacks: {
            initialized: (response: any) => {
               console.log('PaymentSession initialized', response);
            },
            formSessionUpdate: (response: any) => {
               console.log('PaymentSession formSessionUpdate', response);
            },
        },
        interaction: {
            displayControl: {
                formatCard: 'EMBOSSED',
                invalidFieldCharacters: 'REJECT',
            },
        },
    }

With this call the UI elements are changed by the SDK as expected, and a payment can be performed.

Should the user decide not to click a "pay" button (which would call PaymentSession.updateSessionFromForm('card') and successfully store the payment details as necessary) and navigates away ==> the misbahaviour is triggered... Just to make it more clear, when the user naviagates away from the payment page, the HTML elements which the SDK modified are removed from the DOM (these are named in the details object above).

When the user once more comes to the payment page and it issues again the above call (let us call it SECOND_CALL), the UI is not changed and the payment details cannot be inserted in the html input fields (as these remain read-only and detached from the SDK).

It looks like the "session.js" SDK does not clear its linkage to the elements present when FIRST_CALL was issued (and which were removed from the DOM)... So when SECOND_CALL happes, the html elements are not updated

Is there a way to clear the linkage of the "PaymentSession" SDK Objects from the elements of the FIRST_CALL ?

==> This is an SPA and a page refresh should not be an option.

I have asked MPGS support on what to do and this is their current response (which I do not find acceptable):

> The current behavior of session SDK (session.js) is by design, it won’t support multiple calls to configure() if card details fields are deleted and recreated. This will require enhancement to session SDK. We have asked product to review it.
>
> As we mentioned before, this scenario can be supported if merchant hide/show card details fields instead of deleting/recreating. We don’t understand why it can’t be done in SPA. SPA doesn’t mandate to delete/recreate fields, it depends on the underlying implementation.

答案1

得分: 0

我已经弄好了...

我找到的唯一方法是完全从DOM中删除session.js对象,然后重新添加其引用:

mpgsScriptId = 'mpgs-session-js'

detachSdkFromUi() {
    const script = document.getElementById(mpgsScriptId);
    if (script) {
        script.remove();
        PaymentSession = undefined;
    }
}

addMpgsScript() {
    detachSdkFromUi();

    return new Promise<void>((resolve, reject) => {
        const script = document.createElement('script');
        script.id = mpgsScriptId;
        script.async = false;
        script.src = '<session.js的URL>';
        script.onload = () => {
            resolve();
        };
        // 此调用将“PaymentSession”对象插入窗口。
        document.body.append(script);
    });
}

async attachSdkToUi(details: any) {
    await addMpgsScript();

    return new Promise<void>((resolve, reject) =>
        PaymentSession.configure({
            session: details.sessionId,
            fields: {
                card: {
                    number: `#${details.htmlElementIdCardNumber}`,
                    securityCode: `#${details.htmlElementIdCardCCV}`,
                    expiryMonth: `#${details.htmlElementIdCardExpiryMonth}`,
                    expiryYear: `#${details.htmlElementIdCardExpiryYear}`,
                    nameOnCard: `#${details.htmlElementIdCardNameOnCard}`,
                },
            },
            frameEmbeddingMitigation: ['javascript'],
            callbacks: {
                initialized: (response: any) => {
                    console.log('PaymentSession initialized', response);
                    if (response?.status !== 'ok') {
                        reject();
                        return;
                    }

                    resolve();
                },
                formSessionUpdate: (response: any) => {
                    console.log('PaymentSession formSessionUpdate', response);
                },
            },
            interaction: {
                displayControl: {
                    formatCard: 'EMBOSSED',
                    invalidFieldCharacters: 'REJECT',
                },
            },
        })
    );
}

当MPGS发布与SPA兼容的版本时,我可能会重新考虑这个问题...现在可以使用。

英文:

I got it to work...

The only way I found was to completelly remove the session.js objects from the DOM and re-add its reference:

mpgsScriptId = &#39;mpgs-session-js&#39;
detachSdkFromUi() {
const script = document.getElementById(mpgsScriptId);
if (script) {
script.remove();
PaymentSession = undefined;
}
}
addMpgsScript() {
detachSdkFromUi();
return new Promise&lt;void&gt;((resolve, reject) =&gt; {
const script = document.createElement(&#39;script&#39;);
script.id = mpgsScriptId;
script.async = false;
script.src = &#39;&lt;session.js url&gt;&#39;;
script.onload = () =&gt; {
resolve();
};
// this call inserts the &quot;PaymentSession&quot; object into the window.
document.body.append(script);
});
}
async attachSdkToUi(details: any) {
await addMpgsScript();
return new Promise&lt;void&gt;((resolve, reject) =&gt;
PaymentSession.configure({
session: details.sessionId,
fields: {
card: {
number: `#${details.htmlElementIdCardNumber}`,
securityCode: `#${details.htmlElementIdCardCCV}`,
expiryMonth: `#${details.htmlElementIdCardExpiryMonth}`,
expiryYear: `#${details.htmlElementIdCardExpiryYear}`,
nameOnCard: `#${details.htmlElementIdCardNameOnCard}`,
},
},
frameEmbeddingMitigation: [&#39;javascript&#39;],
callbacks: {
initialized: (response: any) =&gt; {
console.log(&#39;PaymentSession initialized&#39;, response);
if (response?.status !== &#39;ok&#39;) {
reject();
return;
}
resolve();
},
formSessionUpdate: (response: any) =&gt; {
console.log(&#39;PaymentSession formSessionUpdate&#39;, response);
},
},
interaction: {
displayControl: {
formatCard: &#39;EMBOSSED&#39;,
invalidFieldCharacters: &#39;REJECT&#39;,
},
},
})
);
}

When MPGS releases a version compatible with SPA's I might revisit this... It will do for now.

huangapple
  • 本文由 发表于 2023年5月25日 08:36:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76328202.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定