11

PayPal SOAP API エンドポイントを web.config または app.config で指定するのではなく、コードで設定する方法を探しています。web.config/app.config ではない環境固有の構成からエンドポイントを読み取って使用する必要があります。

これは可能ですか?github レポジトリで SDK のコードの一部を読みましたが、それは可能ではないように見えますが、何かを見逃していることを願っています。

PayPal Merchant SDK for .Net、バージョン 2.1.96.0 を使用しています。

4

4 に答える 4

6

.config ファイルの外部ですべての重要な設定を指定できるようにする必要がありました。私は怠け者なので、私がやった方法は次のとおりです。

paypalConfig = new Dictionary<string, string>();
paypalConfig.Add("apiUsername", "xxxxx");
paypalConfig.Add("apiPassword", "xxxxx");
paypalConfig.Add("apiSignature", "xxxxx");
==>paypalConfig.Add("mode","live|sandbox");

次に、資格情報を再度指定してメソッドを呼び出す必要があります (これが必要な理由はあまり調査していません)。

var service = new PayPalAPIInterfaceServiceService(paypalConfig);
var doCaptureResponse = service.DoCapture(amount, new SignatureCredential(paypalConfig["apiUsername"], paypalConfig["apiPassword"], paypalConfig["apiSignature"]));
于 2013-04-18T17:29:58.373 に答える
4

回答 2: ただし、PayPal のコードを編集することに問題がなければ、問題なく動作します...

(PayPal: これを読んでいる場合は、この機能を実装してください!!)


編集:これはもはや必要ありません-Simon Labrecqueによる回答を参照してください


したがって、これに何時間も費やし、ライブとサンドボックスの間でエンドポイントを切り替えることができるという期待に基づいてアプリケーションを作成した後 (SOAP サービスを直接呼び出すときと同じように)、ソースをさらに掘り下げて理解することにしました。アウト。

これを機能させるために行った変更を次に示します。

仮定:

手順:

  • PayPal のソース コードを編集し、ローカルでコンパイルしますが、ファイルは 2 つだけです。
  • endpointの下の web.config を空白にし<paypal>ます。おすすめの安全対策!
  • PayPalAPIInterfaceServiceService.cs GitHub からソースをダウンロード(Merchant SDK)
  • DefaultSOAPAPICallHandler.cs GitHub からソースをダウンロード(Core SDK)
  • おそらく、バージョンが nuGet パッケージと同じであることを確認するのに少し時間がかかります。

  • プロジェクトのフォルダーPayPalMerchantSDKなどにこれらの両方のコピーを作成します

  • NuGet のバージョンとの混乱や競合を避けるために、両方のファイルの名前を変更することをお勧めします。私はイライラして、ただ彼らSimonsPayPalAPIInterfaceServiceServiceSimonsSOAPAPICallHandler電話しました - しかし、あなたが望むように彼らに電話してください。

SimonsSOAPAPICallHandler.cs への変更

コンストラクターを変更して boolean を追加しuseSandboxます。

注: すぐに検索と置換の魔法を行うので、最初のパラメーターにする必要があります。

    public SimonsSOAPAPICallHandler(bool useSandbox, string rawPayLoad, string attributesNamespace,
        string headerString)
        : base()
    {
        this.rawPayLoad = rawPayLoad;
        this.nmespceAttributes = attributesNamespace;
        this.headElement = headerString;

        // you can get these from config if you wish but I doubt they'll ever change
        this.endpoint = useSandbox ? "https://api-3t.sandbox.paypal.com/2.0" : "https://api-3t.paypal.com/2.0";
    }

変更GetEndPoint():

    /// <summary>
    /// Returns the endpoint for the API call
    /// </summary>
    /// <returns></returns>
    public string GetEndPoint()
    {
        return this.endpoint;
    }

対応するメンバーを追加します。

    /// <summary>
    /// Endpoint
    /// </summary>
    private string endpoint;

SimonsPayPalAPIInterfaceServiceService.cs への変更

コンストラクターを変更してuseSandboxパラメーターを追加する

public SimonsPayPalAPIInterfaceServiceService(bool useSandbox) 
{ 
    this.useSandbox = useSandbox; 
}

対応メンバー追加

    private bool useSandbox;

このファイルに対して 2 つの検索と置換を行います。それぞれ約100個の交換があります

  • new DefaultSOAPAPICallHandler(と置き換えますnew SimonsSOAPAPICallHandler(useSandbox,
  • DefaultSOAPAPICallHandler defaultHandlerと置き換えますvar defaultHandler

あなたがしたことは、 (ありがたいことに を実装する)useSandboxのコンストラクターにパラメーターとして追加され、各メソッドに対して次のようになります。SimonsSOAPAPICallHandlerIAPICallPreHandler

 public DoExpressCheckoutPaymentResponseType DoExpressCheckoutPayment(DoExpressCheckoutPaymentReq doExpressCheckoutPaymentReq, string apiUserName)
{
    IAPICallPreHandler apiCallPreHandler = null;
    string portName = "PayPalAPIAA";
    setStandardParams(doExpressCheckoutPaymentReq.DoExpressCheckoutPaymentRequest);
    var defaultHandler = new SimonsSOAPAPICallHandler(useSandbox, doExpressCheckoutPaymentReq.ToXMLString(null, "DoExpressCheckoutPaymentReq"), null, null);
    apiCallPreHandler = new MerchantAPICallPreHandler(defaultHandler, apiUserName, getAccessToken(), getAccessTokenSecret());
    ((MerchantAPICallPreHandler) apiCallPreHandler).SDKName = SDKName;
    ((MerchantAPICallPreHandler) apiCallPreHandler).SDKVersion = SDKVersion;
    ((MerchantAPICallPreHandler) apiCallPreHandler).PortName = portName;
    string response = Call(apiCallPreHandler);
    XmlDocument xmlDocument = new XmlDocument();
    xmlDocument.LoadXml(response);
    XmlNode xmlNode = xmlDocument.SelectSingleNode("*[local-name()='Envelope']/*[local-name()='Body']/*[local-name()='DoExpressCheckoutPaymentResponse']");
    return new DoExpressCheckoutPaymentResponseType(xmlNode);

}

それでおしまい!

メソッドを呼び出すと、次のように言うことができます...

bool useSandbox = true; // or false
var service = new SimonsPayPalAPIInterfaceServiceService(useSandbox);

次に、通常どおりメソッドを呼び出します

caller.DoExpressCheckoutPayment(pp_request, config.AccountName);

注: 構成内のアカウント名を検索して、対応するキーを見つけます。Merchant SDK の新しいバージョンに更新する場合は、これを最初からやり直す必要があるため、明らかに注意してください。

誰かがこれが役立つことを願っています:-)

于 2013-02-21T07:42:56.640 に答える
3

それは完全に実行可能ですが、バインディングをオブジェクトとして作成して値をハードコーディングする必要があります。これは私が自分のプロジェクトのために取り組んだものです:

protected static PayPalAPIInterface GetService()
{
    return new PayPalAPIInterfaceClient(new BasicHttpBinding()
            {
                SendTimeout = new TimeSpan(0, 5, 0),
                MaxReceivedMessageSize = 200000,
                Security = new BasicHttpSecurity()
                {
                    Mode = BasicHttpSecurityMode.Transport,
                    Transport = new HttpTransportSecurity()
                                    {
                                        ClientCredentialType = HttpClientCredentialType.None,
                                        ProxyCredentialType = HttpProxyCredentialType.None,
                                    },
                    Message = new BasicHttpMessageSecurity()
                                {
                                    ClientCredentialType = BasicHttpMessageCredentialType.Certificate,
                                }
                }
            },
            new EndpointAddress(@"https://api-3t.paypal.com/2.0/")
        ).ChannelFactory.CreateChannel();
}

設定できるパラメーターは他にもあります。理論的には、.configファイル内のすべてをここで再現できます。ただし、これは私にとってはうまくいくので、それ以上取りませんでした。

これにより、PayPal 呼び出しをライブラリに入れることができ、そのライブラリを含むプロジェクトの構成ファイルにバインディングをコピーする必要がないことも注目に値します。これが、最初に開発した理由です。


編集:これが基本的な定義ですPayPalAPIInterfaceClient-実際に使用するのに十分であるという保証はありません。

public partial class PayPalAPIInterfaceClient : System.ServiceModel.ClientBase<PayPalAPIInterfaceServiceService>
{
    public PayPalAPIInterfaceClient(System.ServiceModel.Channels.Binding binding,
                                    System.ServiceModel.EndpointAddress remoteAddress) 
           : base(binding, remoteAddress) { }
}

また、以前のコードを変更して、代わりに戻り値の型を持たせることもできますPayPalAPIInterfaceServiceService

于 2013-01-24T19:14:04.490 に答える
1

回答1:同意します-箱から出しては不可能です。

コードを自分でコンパイルし、かなり変更しなければ、それは実際には不可能のようです。これが実際に生成されたGitHubの現在のコードです-おそらくT4テンプレートを使用していますPayPalAPIInterfaceServiceServiceこれは、すべてのAPIメソッドに対してこのようなコードを含む大規模な2489行のファイルです。

ここで重要なのはですIAPICallPreHandler。nullに設定されてから、のインスタンスに初期化されていることがわかりますMerchantAPICallPreHandler。それを渡す方法はありません。

    public SetExpressCheckoutResponseType SetExpressCheckout(SetExpressCheckoutReq setExpressCheckoutReq, ICredential credential)
    {
        IAPICallPreHandler apiCallPreHandler = null;
        string portName = "PayPalAPIAA";
        setStandardParams(setExpressCheckoutReq.SetExpressCheckoutRequest);
        DefaultSOAPAPICallHandler defaultHandler = new DefaultSOAPAPICallHandler(setExpressCheckoutReq.ToXMLString(null, "SetExpressCheckoutReq"), null, null);
        apiCallPreHandler = new MerchantAPICallPreHandler(defaultHandler, credential);
        ((MerchantAPICallPreHandler) apiCallPreHandler).SDKName = SDKName;
        ((MerchantAPICallPreHandler) apiCallPreHandler).SDKVersion = SDKVersion;
        ((MerchantAPICallPreHandler) apiCallPreHandler).PortName = portName;
        string response = Call(apiCallPreHandler);
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.LoadXml(response);
        XmlNode xmlNode = xmlDocument.SelectSingleNode("*[local-name()='Envelope']/*[local-name()='Body']/*[local-name()='SetExpressCheckoutResponse']");
        return new SetExpressCheckoutResponseType(xmlNode);

    }

それでは、インターフェースを見てみましょう。

public interface IAPICallPreHandler
{
    ICredential GetCredential();
    string GetEndPoint();
    Dictionary<string, string> GetHeaderMap();
    string GetPayLoad();
}

ドー!GetEndPoint()オーバーライドしたいもののようには見えません。

コードをさらに深く掘り下げるGetEndPoint()と(最終的に呼び出されるインスタンスはこれになります)、ご覧のとおり、DefaultSOAPAPICallHandlerに直接移動しConfigManagerます。

    public string GetEndPoint() 
    {
        return ConfigManager.Instance.GetProperty(BaseConstants.END_POINT);
}

ConfigManagerweb.configまたはに直行しますapp.config

  config = (SDKConfigHandler)ConfigurationManager.GetSection("paypal");

残念ながら、エンドポイントを変更するためのフックなどはありません。

ローカルでコンパイルして修正することを検討しましたが、パッケージ全体をワンクリックで更新する機能を失うよりも、コードでエンドポイントを変更する機能を失いたいと思います。

于 2013-02-21T06:04:16.583 に答える