如果以下链接允许过期的会话登录然后转到交易详细信息页面,或者如果它们已经登录,如果它可以将用户直接带到交易详细信息屏幕,那就太棒了
查看图片
https://live.sagepay.com/mysagepay/login.msp?returnUrl=/transactiondetail.msp?transactionID=68D131EF-3C83-489F-B235-0763752CBDE5
我在 Salesforce 中设置了一个按钮,可以自动将交易 ID 附加到 URL 的末尾,以便我们的前端用户可以轻松查看 SagePay 中的费用,但是如果他们尚未登录,那么它将重定向到登录屏幕,然后一旦登录它就不会像许多网站登录后那样转到 returnUrl。
只要 URL 经过清理,它就不会造成 URL 风险。仅允许相对路径应该会有所帮助,但 SagePays 部分的某些服务器端代码可能需要解析尝试重定向到其他地方的非法请求
查看示例
为什么不让 salesforce 调用 ReportingAPI,然后用返回的详细信息填充屏幕(无论如何,其中包含该屏幕中的所有信息(。
那么,您的用户根本不需要转到 MSP。
下面的代码示例将返回所有事务的列表 - 我相信您可以调整它以使用 getTransactionDetail:
public class Tools {
public static void getTransactions() {
Tools.getTransactionListXML(Tools.executeCommand('getTransactionList', '<startdate>' + Tools.getLastCheckedTime() +'</startdate><enddate>' + Tools.getEndDate() + '</enddate>'));
}
public static String executeCommand(String command, String data) {
GlobalData__c gd = new GlobalData__c();
gd = [SELECT Vendor__c, MSPUsername__c, MSPPassword__c, URL__c FROM GlobalData__c LIMIT 1];
String call='<command>' + command + '</command><vendor>' + gd.Vendor__c + '</vendor><user>' + gd.MSPUsername__c + '</user>' + data;
String HashXML= call + '<password>' + gd.MSPPassword__c + '</password>';
Blob bPrehash = Blob.valueOf(HashXML);
Blob bsig = Crypto.generateDigest('MD5', bPrehash);
String signature = EncodingUtil.convertToHex(bsig);
String xml = '<vspaccess>' + call + '<signature>' + signature + '</signature>' + '</vspaccess>' ;
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setTimeout(120000);
req.setBody('XML=' +xml);
req.setMethod('GET');
req.setHeader('Accept', 'application/xml');
req.setEndpoint(gd.URL__c );
HttpResponse res = h.send(req);
return res.getBody();
}
public static String getLastCheckedTime() {
GlobalData__c gd = new GlobalData__c();
gd = [SELECT TransactionListLastChecked__c FROM GlobalData__c LIMIT 1];
System.debug (gd.TransactionListLastChecked__c);
return (gd.TransactionListLastChecked__c) ;
}
public static String getEndDate() {
//returns day+1 as end date
DateTime myDateTime = DateTime.Now().AddDays(1);
String out = myDateTime.formatLong();
out = out.replace(' GMT', '');
return(out);
}
Public static void getTransactionListXML(String xmlfile) {
//update last checked time
Datetime myDateTime = Datetime.now();
String out = myDateTime.formatLong();
out = out.replace(' GMT', '');
GlobalData__c gd = new GlobalData__c();
gd = [SELECT TransactionListLastChecked__c FROM GlobalData__c LIMIT 1];
gd.TransactionListLastChecked__c = out;
update gd;
DOM.Document xmlDOC = new DOM.Document();
xmlDOC.load(xmlfile);
DOM.XMLNode rootElement = xmlDOC.getRootElement();
Dom.XMLNode vspaccess = xmlDOC.getRootElement();
String errorcode = vspaccess.getChildElement('errorcode', null).getText();
System.debug(errorcode);
Dom.XMLNode transactionsElement = vspaccess.getChildElement('transactions', null);
try{
String totalrows = transactionsElement.getChildElement('totalrows', null).getText();
System.debug(totalrows);
} catch(Exception e) {
System.debug('No rows found.');
return;
}
xmlfile = '<transactions>' + xmlfile.substringBetween('</totalrows>','<timestamp>');
DOM.Document xml2 = new DOM.Document();
xml2.load(xmlfile);
String vpstxid='';
String last4digits = '';
String cardtype='';
String amount='';
String accounttype='';
String authprocessor = '';
String systemused='';
String transactiontype='';
String t3maction='' ;
String repeated='';
String vendordata='';
String website='';
String addressresult='';
String vspauthcode='';
String result='';
String vendorTxCode='';
String curr='';
String bankauthcode='';
String cv2result='';
String threedresult='';
String postcoderesult='';
String cardholder='';
String batchid='';
String refunded='';
String started='';
for(DOM.XMLNode xmlNodeObj:xml2.getRootElement().getChildElements()){
for(DOM.XMLNode xmlNodeObjChild:xmlNodeObj.getChildren())
{
if(xmlNodeObjChild.getName()=='vpstxid')
vpstxid = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='started')
started = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='last4digits')
last4digits = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='paymentsystem')
cardtype = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='amount')
amount = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='accounttype')
accounttype = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='authprocessor')
authprocessor = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='transactiontype')
transactiontype = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='systemused')
systemused = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='t3maction')
t3maction = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='repeated')
repeated = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='vendordata')
vendordata = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='website')
website = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='addressresult')
addressresult = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='vspauthcode')
vspauthcode = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='result')
result = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='vendorTxCode')
vendorTxCode = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='currency')
curr = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='bankauthcode')
bankauthcode = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='cv2result')
cv2result = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='threedresult')
threedresult = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='postcoderesult')
postcoderesult = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='cardholder')
cardholder = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='batchid')
batchid = xmlNodeObjChild.getText();
if(xmlNodeObjChild.getName()=='refunded')
refunded = xmlNodeObjChild.getText();
/*
*/
}
Transactions__c checkTransaction = new Transactions__c ();
Integer cT = [SELECT COUNT() FROM Transactions__c WHERE TransactionID__c=: vpstxid];
System.debug(cT);
Transactions__c newTransaction = new Transactions__c ();
newTransaction.Name = cardholder + ' ' + vendortxcode;
newTransaction.TransactionID__c = vpstxid;
newTransaction.Last4Digits__c = last4digits;
newTransaction.Started__c = started;
newTransaction.Card_Type__c = cardtype;
newTransaction.Amount__c =amount;
newTransaction.AccountType__c= accounttype;
newTransaction.AuthProcessor__c = authprocessor;
newTransaction.TransactionType__c = transactiontype;
newTransaction.SystemUsed__c = systemused;
newTransaction.T3maction__c=t3maction;
newTransaction.Repeated__c=repeated;
newTransaction.VendorData__c=vendordata;
newTransaction.Website__c=website;
newTransaction.AddressResult__c=addressresult;
newTransaction.VSPAuthcode__c=vspauthcode;
newTransaction.Result__c=result;
newTransaction.VendorTxCode__c=vendortxcode;
newTransaction.Currency__c=curr;
newTransaction.BankAuthCode__c=bankauthcode;
newTransaction.CV2Result__c=cv2result;
newTransaction.X3DResult__c=threedresult;
newTransaction.PostcodeResult__c=postcoderesult;
newTransaction.CardHolder__c=cardholder;
newTransaction.BatchID__c=batchid;
newTransaction.Refunded__c=refunded;
if(cT<1)
insert newTransaction;
else
System.debug('Record exists');
}
}
}